[路飞]_leetcode刷题_面试题 04.05. 合法二叉搜索树

1,181 阅读2分钟

题目

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

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

示例 1:

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

示例 2:

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

思路1:

二叉树的前序遍历(递归法)

我们可以把这个问题拆分成小问题,

  • 那么对于每一个节点来说,它要符合二叉搜索树是有一个值的区间范围的,假设范围为(lower,upper)

  • 它自身在这个范围内,且它的左子树和右子树都为二叉搜索树,那么它以及它的子节点就是二叉搜索树

  • 然后我们就可以分别再去分析它的左子节点和右子节点,直接分析到叶子节点为止

  • 叶子节点的子节点为空,那么也是符合二叉搜索树的,所以跳出递归的条件也有了,就是root==null,则return true

  • 初始时,对于根节点来说,lower和upper分别为,-Infinity和Infinity,那么起始条件也有了

代码如下:

/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isValidBST = function(root) {
    return isBST(root,-Infinity,Infinity)
};

function isBST(root,lower,upper){
    if(!root) return true;
    if(root.val<=lower || root.val >= upper) return false;
    return isBST(root.left,lower,root.val) && isBST(root.right,root.val,upper)
}

复杂度分析:

时间复杂度:O(n),n为二叉树节点的数量,因为每个节点都会被遍历一次。

空间复杂度:O(n),递归函数在递归的过程中,需要为每一层额外分配栈空间,那么空间复杂度与二叉树的高度成正比,最坏情况下,二叉树是一条链表,那么高度就是n。

思路2:

对于一个二叉搜索树,中序遍历的结果刚好是一个递增序列,可以从这个思路下手。

  • 中序遍历这个颗二叉树,如果当前值小于下一个值则为二叉搜索树。否则不是。

代码如下:

function isValidBST (root) {
    let stack = [];
    let prev = -Infinity;

    while (stack.length || root) {
        while (root) {
            stack.push(root);
            root = root.left;
        }
        root = stack.pop();
        // 如果中序遍历得到的节点的值小于等于前一个 prev,说明不是二叉搜索树
        if (root.val <= prev) {
            return false;
        }
        prev = root.val;
        root = root.right;
    }
    return true;
}