98. 验证二叉搜索树

本文探讨了三种验证二叉搜索树的有效方法。第一种是通过中序遍历存储节点值并检查升序;第二种优化了中序遍历过程,边遍历边比较;第三种采用递归方式,利用左右子树的边界值辅助判断。每种方法的时间复杂度均为O(n),空间复杂度分别为O(n)和O(1)。
摘要由CSDN通过智能技术生成

LeetCode.98 验证二叉搜索树

1.中序遍历结果为升序
最直观/直接的解法:对二叉搜索树进行中序遍历,将结果存入一个数组,然后判断数组是否为生序即可验证二叉搜索树

private List<Integer> list;
public boolean isValidBST(TreeNode root) {
    list = new ArrayList<>();
    addNode(root);
    // 判断是否为升序
    for (int i = 1; i < list.size(); ++i) {
        if (list.get(i-1)>= list.get(i)) return false;
    }
    return true;
}

// 中序遍历二叉树并添加节点至list
private void addNode(TreeNode root) {
    if (root == null) return;
    addNode(root.left);
    list.add(root.val);
    addNode(root.right);
}

时间复杂度:O(n),分别对树和list进行了一次遍历
空间复杂度:O(n),使用了额外的list来存储元素


2.中序遍历(优化)
通过观察可以发现比较大小这个操作其实可以融合到中序遍历中,省去数组存储和比较的过程。即一边遍历一边比较大小。
在这里插入图片描述
如上图中遍历的顺序是[C, B, E, D, A, F, G],只要在每次新遍历到一个节点时,比较当前节点.val和上一节点.val的大小关系即可判断是否为升序(二叉搜索树)。

private long min = Long.MIN_VALUE;	// 使用long,防止边界值溢出问题
public boolean isValidBST(TreeNode root) {
    if (root == null) return true;
    
    if (!isValidBST(root.left)) return false;

    if (root.val <= min) return false;

    min = root.val;

    return isValidBST(root.right);
}

时间复杂度:O(n)
空间复杂度:O(1)


3.递归(分治)
前两种方法的递归主要侧重于使用中序遍历的顺序来遍历二叉树,除此之外还可以直接递归地解决这个问题,但在递归的同时,必须给子问题传入一个相关提示,即左右边界值:当递归左子树时,任何节点值都不能超过根节点值;当递归右子树时,任何节点值都不能小于根节点值。如此,才能满足二叉搜索树。

public boolean isValidBST(TreeNode root) {
    return isValidBST_helper(root, Long.MIN_VALUE, Long.MAX_VALUE);
}

private boolean isValidBST_helper(TreeNode root, long left, long right) {
    if (root == null) return true;
    if (root.val <= left || root.val >= right) return false;
    return isValidBST_helper(root.left, left, root.val) && isValidBST_helper(root.right, root.val, right);
}

时间复杂度:O(n)
空间复杂度:O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值