leecode/problems/230.kth-smallest-element-in-a-bst.md
2020-05-22 18:17:19 +08:00

190 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 题目地址
https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/
## 题目描述
```
Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.
Note:
You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
Example 1:
Input: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
Output: 1
Example 2:
Input: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
Output: 3
Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
```
## 思路
解法一:
由于中序遍历一个二叉查找树BST的结果是一个有序数组 因此我们只需要在遍历到第k个返回当前元素即可。
中序遍历相关思路请查看[binary-tree-traversal](../thinkings/binary-tree-traversal.md)
解法二:
联想到二叉搜索树的性质root 大于左子树,小于右子树,如果左子树的节点数目等于 K-1那么 root 就是结果,否则如果左子树节点数目小于 K-1那么结果必然在右子树否则就在左子树。
因此在搜索的时候同时返回节点数目,跟 K 做对比,就能得出结果了。
## 关键点解析
- 中序遍历
## 代码
解法一:
JavaScript Code:
```js
/*
* @lc app=leetcode id=230 lang=javascript
*
* [230] Kth Smallest Element in a BST
*/
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
var kthSmallest = function(root, k) {
const stack = [root];
let cur = root;
let i = 0;
function insertAllLefts(cur) {
while(cur && cur.left) {
const l = cur.left;
stack.push(l);
cur = l;
}
}
insertAllLefts(cur);
while(cur = stack.pop()) {
i++;
if (i === k) return cur.val;
const r = cur.right;
if (r) {
stack.push(r);
insertAllLefts(r);
}
}
return -1;
};
```
Java Code:
```java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
private int count = 1;
private int res;
public int KthSmallest (TreeNode root, int k) {
inorder(root, k);
return res;
}
public void inorder (TreeNode root, int k) {
if (root == null) return;
inorder(root.left, k);
if (count++ == k) {
res = root.val;
return;
}
inorder(root.right, k);
}
```
解法二:
JavaScript Code:
```js
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
function nodeCount(node) {
if (node === null) return 0;
const l = nodeCount(node.left);
const r = nodeCount(node.right);
return 1 + l + r;
}
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
var kthSmallest = function(root, k) {
const c = nodeCount(root.left);
if (c === k - 1) return root.val;
else if (c < k - 1) return kthSmallest(root.right, k - c - 1);
return kthSmallest(root.left, k)
};
```
## 扩展
这道题有一个follow up
`What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently?
How would you optimize the kthSmallest routine?`
大家可以思考一下。