验证二叉搜索树

给定一个二叉树,判断其是否是二叉搜索树。

递归。

第一次写的有点问题,有些极端测试用例会无法通过,比如[2147483647](单个Integer.MAX_VALUE)

java 复制代码
class Solution {
    public boolean isValidBST(TreeNode root) {
        return isValidNode(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
    }
    public boolean isValidNode(TreeNode root, int min, int max) {
        if(root == null) return true;
        if((root.val <= min) || (root.val >= max)) return false;
        if(!isValidNode(root.left, min, root.val)) return false;
        return isValidNode(root.right, root.val, max);
    }
}

主要就是最大值和最小值引发的问题,我们就考虑这两个最值出现的情况好了,最值合法出现的情况至多只会出现一次,而且最大值必定没有右节点,最小值也没有左节点,我们就根据这两条来进行判断

改进版,虽然还有问题:(

java 复制代码
class Solution {
    boolean appearMin = false;
    boolean appearMax = false;
    public boolean isValidBST(TreeNode root) {
        return isValidNode(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
    }
    public boolean isValidNode(TreeNode root, int min, int max) {
        if(root == null) return true;
        if((root.val <= min) || (root.val >= max)) {
            if(root.val == Integer.MIN_VALUE) {
                if(appearMin || root.left != null) {
                    return false;
                }
                appearMin = true;
            } else if (root.val == Integer.MAX_VALUE) {
                if(appearMax || root.right != null) {
                    return false;
                }
                appearMax = true;
            } else {
                return false;
            }
        }
        if(!isValidNode(root.left, min, root.val)) return false;
        return isValidNode(root.right, root.val, max);
    }
}

调试了一下发现是在Integer.MIN_VALUE疏忽了和min的比较,也就是说最值还需要考虑是否在区间内。

java 复制代码
class Solution {
    boolean appearMin = false;
    boolean appearMax = false;
    public boolean isValidBST(TreeNode root) {
        return isValidNode(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
    }
    public boolean isValidNode(TreeNode root, int min, int max) {
        if(root == null) return true;
        if((root.val <= min) || (root.val >= max)) {
            if(root.val == Integer.MIN_VALUE) {
                if(appearMin || root.left != null || root.val < min) {
                    return false;
                }
                appearMin = true;
            } else if (root.val == Integer.MAX_VALUE) {
                if(appearMax || root.right != null || root.val > max) {
                    return false;
                }
                appearMax = true;
            } else {
                return false;
            }
        }
        if(!isValidNode(root.left, min, root.val)) return false;
        return isValidNode(root.right, root.val, max);
    }
}

Finally succeed!

看了解析是用中序遍历看是否是单调数组这种思路,相对更直观一些,而且不会有最值的问题。

java 复制代码
class Solution {
    public boolean isValidBST(TreeNode root) {
        if(root == null) return false;
        Stack<TreeNode> st = new Stack<>();
        ArrayList<Integer> list = new ArrayList<>();
        st.push(root);
        while(!st.isEmpty()) {
            TreeNode node = st.pop();
            if(node == null) {
                node = st.pop();
                list.add(node.val);
                continue;
            }
            if(node.right != null) {
                st.push(node.right);
            }
            st.push(node);
            st.push(null);
            if(node.left != null) {
                st.push(node.left);
            }
        }
        for (int i = 0; i < list.size() - 1; i++) {
            if(list.get(i) >= list.get(i+1)) return false;
        }
        return true;
    }
}

把上述代码优化一下,不额外用数组结构。

java 复制代码
class Solution {
    public boolean isValidBST(TreeNode root) {
        if(root == null) return false;
        Stack<TreeNode> st = new Stack<>();
        st.push(root);
        Integer pre = null;
        Integer cur = null;
        while(!st.isEmpty()) {
            TreeNode node = st.pop();
            if(node == null) {
                node = st.pop();
                cur = node.val;
                if(pre != null && cur <= pre) return false;
                pre = node.val;
                continue;
            }
            if(node.right != null) {
                st.push(node.right);
            }
            st.push(node);
            st.push(null);
            if(node.left != null) {
                st.push(node.left);
            }
        }
        return true;
    }
}

还有个有点投机取巧的方法,既然Integer的最值不行,就换成Long的最值

java 复制代码
class Solution {
    public boolean isValidBST(TreeNode root) {
        return isValidNode(root, Long.MIN_VALUE, Long.MAX_VALUE);
    }
    public boolean isValidNode(TreeNode root, Long min, Long max) {
        if(root == null) return true;
        if((root.val <= min) || (root.val >= max)) return false;
        if(!isValidNode(root.left, min, (long)root.val)) return false;
        return isValidNode(root.right, (long)root.val, max);
    }
}

虽然能够通过,但是终究只是回避了最值的问题,如果节点的值能够取到Long的最值依然会出现问题。


参考链接:

【代码随想录】-验证二叉搜索树


由于作者水平有限,错误和不当之处在所难免,敬请各位斧正。

相关推荐
汀、人工智能6 分钟前
[特殊字符] 第77课:最长递增子序列
数据结构·算法·数据库架构·图论·bfs·最长递增子序列
网域小星球7 分钟前
C语言从0入门(十)|二维数组详解与矩阵实战
c语言·算法·矩阵·二维数组·数组遍历
澈20712 分钟前
堆排序:高效构建大顶堆实战
数据结构·算法·排序算法
我真不是小鱼34 分钟前
cpp刷题打卡记录27——无重复字符的最长子串 & 找到字符串中所有字母的异位词
数据结构·c++·算法·leetcode
XuecWu339 分钟前
原生多模态颠覆Scaling Law?解读语言“参数需求型”与视觉“数据需求型”核心差异
人工智能·深度学习·算法·计算机视觉·语言模型
We་ct39 分钟前
LeetCode 69. x 的平方根:两种解法详解
前端·javascript·算法·leetcode·typescript·平方
一直不明飞行41 分钟前
C++:string,写法s.find(‘@‘) != s.end()是否有问题
开发语言·c++·算法
Proxy_ZZ01 小时前
打造自己的信道编码工具箱——Turbo、LDPC、极化码三合一
c语言·算法·信息与通信
wayz111 小时前
21天机器学习核心算法学习计划(量化方向)
学习·算法·机器学习
穿条秋裤到处跑1 小时前
每日一道leetcode(2026.04.09):区间乘法查询后的异或 II
算法·leetcode