大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。
题目
230. 二叉搜索树中第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 <= 1040 <= Node.val <= 104
进阶: 如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?
思路
- 首先由于我们已经拿到了一颗二叉搜索树,这意味着中旬遍历时候是从左到右递增的,那么我们只需要找到哪个节点是第k个节点即可;
- 我们可以用栈缓存一下已经记录过的节点,然后每次从栈中取出一个节点,判断它是否有左节点,有的话就把它的左节点放进栈中做下一轮同样的操作,同时把当前节点的左节点重置为空;
- 当我们找到最左边的节点的时候,说明我们已经找到了中序遍历的第一个节点,然后把它的值放到
result数组中记录一下中序遍历的每个节点, 当然也可以直接--k, 当k减到0时返回那个节点即可; - 找到最左边了,我们还得一轮轮回去找每个节点的右边节点,具体的实现是这样子的,拿到栈中最后一个节点,然后判断是否有左节点,有的话隔断关系放入栈中继续寻找,没有的话取出并记录当前节点,然后判断当前节点是否有右节点,如果有的话就把右节点入栈;
- 最终找到我们要的节点直接返回即可。
实现
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
var kthSmallest = function(root, k) {
let stack = [ root ];
while (stack.length) {
let cur = stack[stack.length - 1];
if (cur.left) {
stack.push(cur.left);
cur.left = null;
} else {
--k;
stack.pop();
if (cur.right) {
stack.push(cur.right);
}
}
if (k === 0) {
return cur.val;
}
}
};
结果
看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。