230. Kth Smallest Element in a BST
来源:互联网 发布:列宁格勒 知乎 编辑:程序博客网 时间:2024/05/17 03:23
题目:
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.
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?
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).
题意:
给定一个二叉搜索树,写一个功能kthSmallest用来找到该二叉树中第K小的元素。
二叉搜索树:它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。即根节点的值是中间值,左子树的值均小于根节点的值,右子树的值均大于根节点的值。
note:
可以假设k总是有效的,1 ≤ k ≤二叉搜索树总的节点数量。
Follow up:
如果BST的修改(插入/删除)操作十分频繁,并且需要频繁地找出第k小的元素,应该怎样优化kthSmallest函数?
Hint:
1、尝试利用BST的属性。
2、如果你可以修改BST节点的结构时,应该怎样做?
3、最优时间复杂度应该是O(BST的高度)。
思路一:
利用堆栈实现,利用堆栈实现中序遍历,首先找到最左边的元素,即为该二叉搜索树的最小值,将从根节点开始的所有左子树的根节点都保存在堆栈中,以备左右子树切换时使用,每找到一个左子树叶子节点,则k减一,病切换到右子树去查询,直到k为0为止,返回该节点的值即可。非递归版。
代码:java版:2ms
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */public class Solution { public int kthSmallest(TreeNode root, int k) { Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode node = root; while (node.left != null) { //将所有的左子树入栈 stack.push(node); node = node.left; } while (k>0 && (node!=null || !stack.isEmpty())) { if (node == null) { //如果节点为空 node = stack.pop(); //找到其父节点 if (--k == 0) //找到第k小的元素 return node.val; node = node.right; //找右子树 } else { stack.push(node); node = node.left; } } return node.val; }}代码:C++版:20ms
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */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; }};
思路二:
利用计算二叉树节点数量的子函数,计算出根节点左子树的总的节点数量,然后比较左子树节点数量与k值得大小,如果k值小于左子树节点数目,则说明该值在左子树中,继续对左子树进行迭代处理,如果大于,则说明k值最小的节点在右子树中,则对右子树进行迭代处理,并且减掉前面左子树数目的k值。
代码:C++版:24ms
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class Solution {public: int kthSmallest(TreeNode* root, int k) { if (root == NULL) return 0; int leftSize = treeSize(root->left); if (k == leftSize+1) { return root->val; } else if (leftSize >= k) { return kthSmallest(root->left, k); } else { return kthSmallest(root->right, k-leftSize-1); } } int treeSize(TreeNode* root) { //计算根节点下有多少节点 if (root == NULL) return 0; return 1 + treeSize(root->left) + treeSize(root->right); }};
思路三:
直接递归实现,依然基于中序遍历的思想。
代码:C++版:20ms
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */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) return val; if (!--k) return root->val; return kthSmallestDFS(root->right, k); }};
- 230.Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 230. Kth Smallest Element in a BST
- 基于bootstrap和php的项目
- gcc 编译过程
- C++ 字符char相关操作
- poj3253
- merge into和on duplicate key
- 230. Kth Smallest Element in a BST
- 开发 - kafka的一次小坑
- javascript之location对象
- 凸优化学习笔记(1)——凸集
- 天梯赛 L2-012. 关于堆的判断 数据结构
- 直观解释Gamma分布和Poisson分布
- 小京东版权修改
- SimpleAdapter.ViewBinder方法的感受
- C&C++学习笔记2