[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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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:
1 2 3 4 5 6 7 8 9 10 11 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 题目汇总
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步