剑指 Offer 54. 二叉搜索树的第k大节点
给定一棵二叉搜索树,请找出其中第 k 大的节点的值。
示例 1:
输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
示例 2:
输入: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
输出: 4
限制:
1 ≤ k ≤ 二叉搜索树元素个数
解题思路:什么是二叉搜索树,就是中序遍历后是从小到大的排序,例如实例1中,中序遍历后就是[1,2,3,4],实例二中[123456],还有一个特点就是根节点的左边小于根节点,右边大于根节点,第k大节点的意思就是找出倒数第k个节点,代码如下 实现方式一:中序遍历
var kthLargest = function(root, k) {
//保存所有节点数组
let ans = [];
//通过递归将所有节点存储在ans中
let ansAll = _kthLargest(root,ans);
//返回倒数第k个值
return ansAll[ansAll.length - k];
};
//递归函数
var _kthLargest = function(root,ans){
if(!root) return;
//遍历左子树
_kthLargest(root.left,ans);
//先保存左节点然后保存根节点
ans.push(root.val);
//遍历右子树
_kthLargest(root.right,ans);
return ans;
}
实现方式二:根据k的大小来判断,k如果小于等于右子树节点个数,那么k在右子树上,如果k等于右子树节点加一那么第k大节点就是根节点,如果大于右子树那么就在左子树上找,代码如下:
var kthLargest = function(root, k) {
//获取右子树节点个数
let r = getHight(root.right);
//如果k小于等于r那么需要返回的数在右子树上
if( k <= r ) return kthLargest(root.right,k);
//直到k等于r+1那么就找到了需要返回的第k大节点了
if(k === r + 1) return root.val;
//此时可以判断第k大节点数在左子树上,通过递归可以找到
return kthLargest(root.left,k - r -1);
};
var getHight = function(root){
if(!root) return 0;
//累计节点个数
return getHight(root.left) + getHight(root.right) + 1;
}