LeetCode: 第98题 - 验证二叉搜索树

原题链接:98. 验证二叉搜索树

 

目录

解法一:(推荐)

思路:

解题步骤:

算法实现:

代码

递归过程图:

解法二:

思路:

解题步骤:

代码


解法一:(推荐)

思路:

如果一个二叉树是有效的二叉搜索树,那么使用中序遍历则一定可以得到一个有序的序列。所以问题就变为在中序遍历的同时判断二叉树是不是有序的。

解题步骤:

(1)使用一个长整型变量prev记录前一个结点的值,cur.val为当前结点的值

(2)判断当前节点值是否大于中序遍历中的前一个节点的值,若大于则继续递归,否则返回false。

PS: 因为题目给出的最小值为 -2^31,所以需要用一个比它更小的值表示第一个中序遍历结点的前一个值)

算法实现:

这里使用序列 [5,4,6,null,null,3,7] 做例子。

LeetCode: 第98题 - 验证二叉搜索树_第1张图片

代码

   /**
     * 时间复杂度:O(n) n为树结点个数,每个结点需要被访问一次。
     *
     * 空间复杂度:O(n) n为树结点个数,函数递归过程中需要在栈上开辟的空间,最坏情况下,
     * 树为单分支链表,递归层次达到n,空间复杂度为O(n);
     */

public class IsValidBST {

    private long prev = Long.MIN_VALUE;

    public boolean isValidBST(TreeNode root) {
        if (root == null) return true; //空直接返回true

        if (!isValidBST(root.left)) { //若左子树不满足条件则返回false
            return false;
        }

        if (root.val > prev) { //判断当前节点值是否大于中序遍历中的前一个节点的值,若大于则继续递归,否则返回false。
            prev = root.val; //prev改为当前结点
            return isValidBST(root.right);
        } else {
            return false;
        }
    }

}

 递归过程图:

LeetCode: 第98题 - 验证二叉搜索树_第2张图片

 LeetCode: 第98题 - 验证二叉搜索树_第3张图片

 LeetCode: 第98题 - 验证二叉搜索树_第4张图片

 LeetCode: 第98题 - 验证二叉搜索树_第5张图片

解法二:

思路:

使用中序遍历将各结点值放入list中,然后遍历list,如果list有序则是有效的二叉搜索树,否则不是。

解题步骤:

(1)创建list用来保存结点值。

(2)中序遍历树,并添加各结点

(3)再遍历list判断是否为有序的

代码

/**
 *    时间复杂度:0(2N),去掉常数项为0(N) N为树的结点个数,遍历树一次为N,遍历list一次也为N。
 *
 *    空间复杂度:O(N) 而且还要考虑list扩容耗费的时间,若直接将list初始化为最大则浪费大量空间。
 */
ArrayList list = new ArrayList<>();

public boolean isValidBST(TreeNode root) {
    inorder(root);
    for(int i = 0; i < list.size() - 1; i++){
        if(list.get(i) >= list.get(i+1)){
            return false;
        }
    }
    return true;
}

public void inorder(TreeNode root){
    if(root == null){
        return;
    }
    isValidBST(root.left);
    list.add(root.val);
    isValidBST(root.right);
}

你可能感兴趣的:(leetcode,算法,数据结构)