44.二叉搜索树中第 K 小的元素(学习)
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)。
示例 1:
输入:root = [3,1,4,null,2], k = 1
输出:1
示例 2:
输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3
提示:
树中的节点数为 n 。
1 <= k <= n <= 104
0 <= Node.val <= 104
解析:
一、局部变量
1.count:当我们进行中序遍历时,每访问一个节点,count就会增加1。它帮助我们跟踪当前是第几个节点。
2.result:当我们找到第k个节点时,它的值会被存储在result中。
二、中序遍历函数
1.遍历左子树:首先,我们递归地遍历当前节点的左子树。由于二叉搜索树的性质,左子树中的所有节点值都小于当前节点的值。
2.访问当前节点:当我们从左子树返回时,我们访问当前节点(即根节点)。我们增加count的值,并检查它是否等于k。如果是,我们将当3前节点的值存储在result中,并提前结束遍历(因为我们已经找到了第k小的元素)。
3.遍历右子树:如果count不等于k,我们继续递归地遍历当前节点的右子树。右子树中的所有节点值都大于当前节点的值。
三、调用中序遍历
1.在kthSmallest函数的末尾,我们调用inorderTraversal函数从根节点开始中序遍历。由于中序遍历的性质,遍历的结果是一个递增的节点值序列。当遍历到第k个节点时,我们将该节点的值存储在result中,并在遍历完成后返回它。
var kthSmallest = function (root, k) {
let count = 0; // 用于记录遍历的节点数
let result = null; // 存储第k小的元素
// 定义中序遍历的函数
function inorderTraversal(node) {
if (!node) return; // 如果节点为空,直接返回
inorderTraversal(node.left); // 遍历左子树
count++; // 遍历到一个节点,计数器加1
// 如果当前是第k个节点,则保存其值
if (count === k) {
result = node.val;
return; // 找到第k个节点后,可以提前结束遍历
}
inorderTraversal(node.right); // 遍历右子树
}
inorderTraversal(root); // 从根节点开始中序遍历
return result; // 返回第k小的元素
};