「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战」
前言
今天进了二叉树的新品种,人称二叉搜索树,简单来说就是按中序遍历的二叉树,每个节点的值都是按升序排的,我们要做的是找出二叉搜索树中的第k大节点。
题目描述
剑指 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:1->2->3->4
例2:1->2->3->4->5->6 - 那么我们要找第k大节点,如果按照中序遍历找第k小比较方便,那么我们
逆向的中序遍历就把节点值从大到小的降序排列了 - 由于
递归是深度优先执行,也就是最内层的函数最先执行,我们只要按照逆向的中序遍历--右->中->左去递归遍历即可,最右边的节点在最内层递归函数里会最先执行,依次往外执行。
开始解题
代码逻辑整理:
- 判断节点二叉树root节点是否存在
- 声明并初始化一个max值来存第k大节点的值
定义递归遍历二叉树的函数reverseMid并对k进行执行递减的操作,当k值减为0时,此时遍历的这个节点的值就是二叉搜索树的第k大节点- 传入root根执行递归函数
- 返回max及第k大节点的值
var kthLargest = function(root, k) {
if(!root) return null;
let max = 0;
const reverseMid = (node) => {
if(!node) return null;
reverseMid(node.right); // 右边会先一直递归找到底,然后从最内层执行完了才开始执行下面的,可以看成是根右子树->根->根左子树
if(!--k) return max = node.val; // 因为遍历到当前节点,相当于执行了一次k递减操作,所有要先减再判断
reverseMid(node.left);
}
reverseMid(root);
return max;
};