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?
给一个二叉树,写一个找到第k小元素的函数。Follow up: 二叉树经常被修改,需要频繁找第k小的元素,如何优化。
解法1:提示让用BST的性质来,那就是BST数值大小是:左<根<右,用中序遍历所有的节点就会得到一个有序数组,如果只求第k小的数,还可以用一个计数器记录已经遍历的节点数,只遍历到第k个节点返回即可。
解法2: 新的题目里已经去掉提示了,所以也可以有别的解法。
Hint:
Try to utilize the property of a BST.
What if you could modify the BST node's structure?
The optimal runtime complexity is O(height of BST).
1、计算左子树元素个数left。
2、 left+1 = K,则根节点即为第K个元素, left >= k, 则第K个元素在左子树中,left +1 < k, 则转换为在右子树中,寻找第K-left-1元素。
Java:
public int kthSmallest(TreeNode root, int k) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = root;
while(p!=null){
stack.push(p);
p=p.left;
}
int i=0;
while(!stack.isEmpty()){
TreeNode t = stack.pop();
i++;
if(i==k)
return t.val;
TreeNode r = t.right;
while(r!=null){
stack.push(r);
r=r.left;
}
}
return -1;
}
Java:
public int kthSmallest(TreeNode root, int k) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = root;
int result = 0;
while(!stack.isEmpty() || p!=null){
if(p!=null){
stack.push(p);
p = p.left;
}else{
TreeNode t = stack.pop();
k--;
if(k==0)
result = t.val;
p = t.right;
}
}
return result;
}
Python:
def kthSmallest(root, k):
stack = []
while root or stack:
while root:
stack.append(root)
root = root.left
root = stack.pop()
k -= 1
if k == 0:
return root.val
root = root.right
Python:
class Solution:
# @param {TreeNode} root
# @param {integer} k
# @return {integer}
def kthSmallest(self, root, k):
s, cur, rank = [], root, 0
while s or cur:
if cur:
s.append(cur)
cur = cur.left
else:
cur = s.pop()
rank += 1
if rank == k:
return cur.val
cur = cur.right
return float("-inf")
C++:Iteration
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
int cnt = 0;
stack<TreeNode*> s;
TreeNode *p = root;
while (p || !s.empty()) {
while (p) {
s.push(p);
p = p->left;
}
p = s.top(); s.pop();
++cnt;
if (cnt == k) return p->val;
p = p->right;
}
return 0;
}
};
C++:Recursion
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
return kthSmallestDFS(root, k);
}
int kthSmallestDFS(TreeNode* root, int &k) {
if (!root) return -1;
int val = kthSmallestDFS(root->left, k);
if (k == 0) return val;
if (--k == 0) return root->val;
return kthSmallestDFS(root->right, k);
}
};
C++:
class Solution {
public:
int kthSmallest(TreeNode* root, int k) {
if(root==NULL)
return 0;
int leftSize=calNode(root->left);
if(leftSize+1 == k)
return root->val;
else if(leftSize+1 < k)
return kthSmallest(root->right,k-leftSize-1);
else
return kthSmallest(root->left,k);
}
int calNode(TreeNode *head){
if(head==NULL)
return 0;
return calNode(head->left)+calNode(head->right)+1;
}
};
类似题目:
[LeetCode] 94. Binary Tree Inorder Traversal 二叉树的中序遍历
All LeetCode Questions List 题目汇总