[LeetCode] 230. Kth Smallest Element in a BST 二叉搜索树中的第K小的元素
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 题目汇总