验证二叉搜索树

题面

给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。

有效 二叉搜索树定义如下:

  • 节点的左子树只包含 严格小于 当前节点的数。
  • 节点的右子树只包含 严格大于 当前节点的数。
  • 所有左子树和右子树自身必须也是二叉搜索树。

示例 1:

输入: root = [2,1,3] 输出: true

示例 2:

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

提示:

  • 树中节点数目范围在[1, 104] 内
  • -231 <= Node.val <= 231 - 1

分析

  • 可以通过中序遍历,得到一个数组,然后判断该数组是否为升序的即可

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
     *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
     *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
     * right(right) {}
     * };
     */
    class Solution {
    public:
        bool isValidBST(TreeNode* root) {
            if (root == nullptr)
                return true;
            stack<TreeNode*> st;
            TreeNode* cur = root;
            vector<int> res;
            while (cur != nullptr || !st.empty()) {
                if (cur != nullptr) {
                    st.push(cur);
                    cur = cur->left;
                } else {
                    cur = st.top();
                    st.pop();
                    res.push_back(cur->val);
                    cur = cur->right;
                }
            }
            for (int i = 1; i < res.size(); i++) {
                if (res[i] <= res[i - 1])
                    return false;
            }
            return true;
        }
    };
  • 实际上,可以直接将二叉树看作是一个数组,在遍历的过程中直接进行比较,这时需要记录一个 pre 表示根节点的值

    class Solution {
        long long pre = LLONG_MIN;
    public:
        bool isValidBST(TreeNode* root) {
            if (root == nullptr) {
                return true;
            }
            if (!isValidBST(root->left)) { // 左
                return false;
            }
            if (root->val <= pre) { // 中
                return false;
            }
            pre = root->val;
            return isValidBST(root->right); // 右
        }
    };
  • 前序遍历:额外传入两个参数,分别表示从根到当前节点路径上的最小值和最大值,当前节点的值必须在最小值和最大值之间(不能等于)

    class Solution {
    public:
        bool isValidBST(TreeNode* root, long long left = LLONG_MIN, long long right = LLONG_MAX) {
            if (root == nullptr) {
                return true;
            }
            long long x = root->val;
            return left < x && x < right &&
                   isValidBST(root->left, left, x) &&
                   isValidBST(root->right, x, right);
        }
    };
  • 后序遍历:返回子树的最小值和最大值,供上面的节点判断是否为二叉搜索树

    class Solution {
        pair<long long, long long> dfs(TreeNode* node) {
            if (node == nullptr) {
                return {LLONG_MAX, LLONG_MIN};
            }
            auto[l_min, l_max] = dfs(node->left);
            auto[r_min, r_max] = dfs(node->right);
            long long x = node->val;
            // 也可以在递归完左子树之后立刻判断,如果发现不是二叉搜索树,就不用递归右子树了
            if (x <= l_max || x >= r_min) {
                return {LLONG_MIN, LLONG_MAX};
            }
            return {min(l_min, x), max(r_max, x)};
        }
    
    public:
        bool isValidBST(TreeNode* root) {
            return dfs(root).second != LLONG_MAX;
        }
    };
这篇文档有帮助吗?

On this page

页面信息