[前端]_一起刷leetcode 面试题 04.05. 合法二叉搜索树

133 阅读3分钟

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

题目

面试题 04.05. 合法二叉搜索树

实现一个函数,检查一棵二叉树是否为二叉搜索树。

示例 1:

输入: 
    2
   / \
  1   3
输出: true

示例 2:

输入: 
    5
   / \
  1   4
     / \
    3   6
输出: false
解释: 输入为: [5,1,4,null,null,3,6]。
     根节点的值为 5 ,但是其右子节点值为 4

思路

  1. 首先做这道题目之前,得明白什么是二叉搜索数,下面复制一下由百度百科借鉴过来的一段解释:

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树

  1. 那么问题就简单起来了,我们只需要证明从左往右依次是累加的即可,这不正好符合中序遍历的特点嘛;
  2. 我们可以直接判断数组的中序遍历是否是一个递增的序列即可;
  3. 为了简化操作,我们可以用prev缓存一下上一个节点, 只要当前上一个节点小于等于当前节点我们就结束循环,不往下执行。

实现

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isValidBST = function(root) {
    if (!root) return true;

    let stack = [ root ];
    // 一开始是最小值,谁都比它大
    let prev = Number.MIN_SAFE_INTEGER;

    // 这里用迭代方便待会儿跳出循环
    while (stack.length) {
        let cur = stack[stack.length - 1];
        // 如果有左节点,继续深究左节点
        if (cur.left) {
            stack.push(cur.left);
            cur.left = null;
        } else {
            // 没有左节点了,中序遍历中就排到根节点了
            if (cur.val > prev) {
                // 更新上一轮的值
                prev = cur.val;
                // 删除当前根节点
                stack.pop();
                // 如果有右节点丢进下一轮
                cur.right && stack.push(cur.right);
            } else {
                // 直接结束循环
                return false;
            }
        }
    }

    // 遍历结束,说明大家都符合条件
    return true;
};

结果

image.png

递归解法

思路

  1. 首先我们可以判断当前节点是否有左节点,如果有的话左节点的值是否小于当前节点的值;
  2. 其次我们可以判断当前节点是否有右节点,如果有的话右节点的值是否大于当前节点的值;
  3. 当时这样子的话我们还得维护当前节点的值和上一轮节点的值的关系,这样子就很麻烦;
  4. 但是我们可以换种方式,限定每个节点取值的所在区间,比如说上一轮的根节点的值是5, 那么左节点的值都应该小于5,右节点的值都应该大于5,一层一层的区间传递下去,如果有一个值不在区间内则结束。

实现

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isValidBST = function(root, minValue = Number.MIN_SAFE_INTEGER, maxValue = Number.MAX_SAFE_INTEGER) {

    if (!root) return true;

    // 只要不满足一个条件,就出局
    if (root.val <= minValue || root.val >= maxValue) {
        return false;
    }

    // 让每个数字都只能在指定区间内活动
    return isValidBST(root.left, minValue, root.val) && isValidBST(root.right, root.val, maxValue);
};

结果

image.png

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