采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
bobo老师,您好!刚买了您这门课,我想请教一下如何用BST实现从数组中获取前K个最小数,我想了很久一直没有思路😂,感谢!
在BST中找到第k小的树是一个很经典的面试问题:)
整体大概思路是:由于BST中,根节点的左子树的所有值都小于根节点;右子树的所有值都大于根节点。所以,我们要求整棵树的第k小元素,只要看根节点的左子树有多少个元素就好了。
如果根节点的左子树包含的元素个数left_num == k - 1,那么,根节点就是第k个元素!
如果根节点的左子树包含的元素个数left_num < k - 1,那么,整棵树的第k小元素在根节点的左子树中,我们继续找根节点的左子树的第k小元素就好了。
如果根节点的左子树包含的元素个数left_num > k - 1,那么,整棵树的第k小元素在根节点的右子树中,我们继续找根节点的右子树的第k - left_num - 1小元素就好了,这个数字是我们排除到了左子树的元素个数以及根节点:)
代码如下:(Java)
// Definition for binary tree:
// class Tree<T> {
// Tree(T x) {
// value = x;
// }
// T value;
// Tree<T> left;
// Tree<T> right;
// 递归计算二分搜索树t的节点个数
int
num(Tree<Integer> t){
if
(t ==
null
)
return
0
;
1
+ num(t.left) + num(t.right);
}
// 求二分搜索树t的第k小元素
kthSmallestInBST(Tree<Integer> t,
k) {
// 计算t的左子树节点个数
left = num(t.left);
// 如果左子树节点个数 + 1(根节点)就是k,当前根节点就是结果
(k == left +
t.value;
// 如果 k <= left,则继续在t的左子树寻找第k小元素
(k <= left)
kthSmallestInBST(t.left, k);
// 否则,在t的右子树寻找第k - left - 1小元素
kthSmallestInBST(t.right, k - left -
);
在上面的代码中,我们使用了一个子过程来计算一棵树的节点个数。但是,可以再建树的过程中,在Node里存储一个size,用于记录以当前Node为根节点的树的节点总数,并且在添加新节点或者删除节点的时候,对size进行维护。这样做,在计算第k小节点的时候,就不需要重复计算一棵树的节点总数了。可以试试看:)
上面的代码是获得第k小的节点。如果要想获得前k个节点,整体思路也是一致的,具体实现上要有一些小改动,有兴趣也可以试试看:)
加油!:)
了解,但当原数组含有重复的几个比较小的数时,如[1,3,1,4],BST里并不包含相同的节点,那就取不出两个1,可以这么理解吗?
你可以让自己的BST可以接受相同节点,也可以用BSTMap的方式,每个节点记录只是多少,以及这个值在数组中有多少个。逻辑会复杂一些,但是整体思路依然可以做:)
非常感谢!
登录后可查看更多问答,登录/注册
动态数组/栈/队列/链表/BST/堆/线段树/Trie/并查集/AVL/红黑树…
10.6k 16
1.5k 17
1.4k 14
购课补贴联系客服咨询优惠详情
慕课网APP您的移动学习伙伴
扫描二维码关注慕课网微信公众号