[前端]_一起刷leetcode 230. 二叉搜索树中第K小的元素

99 阅读2分钟

大家好,我是挨打的阿木木,爱好算法的前端摸鱼老。最近会频繁给大家分享我刷算法题过程中的思路和心得。如果你也是想提高逼格的摸鱼老,欢迎关注我,一起学习。

题目

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 <= 104
  • 0 <= Node.val <= 104

 

进阶: 如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?

思路

  1. 首先由于我们已经拿到了一颗二叉搜索树,这意味着中旬遍历时候是从左到右递增的,那么我们只需要找到哪个节点是第k个节点即可;
  2. 我们可以用栈缓存一下已经记录过的节点,然后每次从栈中取出一个节点,判断它是否有左节点,有的话就把它的左节点放进栈中做下一轮同样的操作,同时把当前节点的左节点重置为空;
  3. 当我们找到最左边的节点的时候,说明我们已经找到了中序遍历的第一个节点,然后把它的值放到result数组中记录一下中序遍历的每个节点, 当然也可以直接--k, 当k减到0时返回那个节点即可;
  4. 找到最左边了,我们还得一轮轮回去找每个节点的右边节点,具体的实现是这样子的,拿到栈中最后一个节点,然后判断是否有左节点,有的话隔断关系放入栈中继续寻找,没有的话取出并记录当前节点,然后判断当前节点是否有右节点,如果有的话就把右节点入栈;
  5. 最终找到我们要的节点直接返回即可。

实现

/**
 * 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;
        }
    }
};

结果

image.png

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。