力扣_合法二叉搜索树_dfs

二叉搜索树(又:二叉查找树,二叉排序树)——Binary Search Tree

力扣_合法二叉搜索树_dfs_第1张图片

解法一、递归

函数递归调用的入口为 helper(root, -inf, +inf), inf 表示一个无穷大的值。

class Solution {
public:
    bool helper(TreeNode* root, long long lower, long long upper) {
        if (root == nullptr) {
            return true;
        }
        if (root -> val <= lower || root -> val >= upper) {
            return false;
        }
        return helper(root -> left, lower, root -> val) && helper(root -> right, root -> val, upper);
    }
    bool isValidBST(TreeNode* root) {
        return helper(root, LONG_MIN, LONG_MAX);
    }
};

这里的lower和upper的设置很有意思,可以仔细思考一下,以下是我的理解:
比如一棵树是[10,5,15,null,null,6,20],因为6在10的右子树上,故他不是二叉搜索树。那么这时候这里的lower和upper就派上用场了,最开始我写的是

return helper(root -> left, LONG_MIN, root -> val) && helper(root -> right, root -> val, LONG_MAX);

其实这就是没有完全理解二叉搜索树,因为以上的代码只是和[15,6,20]这棵子树进行了比较判断,并没有和10进行判断,这里lower和upper为传值操作(具体的c++函数传参可以参考此处链接),它的值跟随着递归一直在变化,自己推一下就可以知道其实这步判断正确的应该是helper(6,10,15),也就是此时的lower已经变为10了,输出才为false。如果还是LONG_MIN,那么他其实是没有和10进行比较的,输出true导致解答错误。

解法二、中序遍历

中序遍历是二叉树的一种遍历方式,它先遍历左子树,再遍历根节点,最后遍历右子树。而我们二叉搜索树保证了左子树的节点的值均小于根节点的值,根节点的值均小于右子树的值,因此中序遍历以后得到的序列一定是升序序列。

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        stack stack;
        long long inorder = (long long)INT_MIN - 1;

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

力扣_合法二叉搜索树_dfs_第2张图片

Reference

https://leetcode-cn.com/problems/legal-binary-search-tree-lcci/solution/he-fa-er-cha-sou-suo-shu-by-leetcode-sol-y1xm/

你可能感兴趣的:(C++)