leetcode_[python/C++]_98_Validate Binary Search Tree

题目链接
【题目】

Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

The left subtree of a node contains only nodes with keys less than the node’s key.
The right subtree of a node contains only nodes with keys greater than the node’s key.
Both the left and right subtrees must also be binary search trees.
【解析】
题意:判断一个二叉树是否为二分查找树。

何为二分查找树?1) 左子树的值都比根节点小;2) 右子树的值都比根节点大;3) 左右子树也必须满足上面两个条件。


C++


(1)中序遍历,暴力递归(AC)【慢】

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        if(root == NULL) return true;
        if(!valid_left(root->left, root->val)||!valid_right(root->right,root->val)) return false;
        return (isValidBST(root->left) && isValidBST(root->right));
    }
    bool valid_left(TreeNode* root, int value){
        if(root == NULL ) return true;
        if(root->val >= value) return false;
        return valid_left(root->left,value)&&valid_left(root->right,value);
    }
    bool valid_right(TreeNode* root, int value){
        if(root == NULL ) return true;
        if(root->val <= value) return false;
        return valid_right(root->left,value)&&valid_right(root->right,value);
    }

};

(2)最大最小值比较,递归(Not AC)网上有人说以前是可以AC的

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        return min_max_judge(root,INT_MIN,INT_MAX);
    }
    bool min_max_judge(TreeNode* root,int min_value, int max_value){
        if(root == NULL) return true;
        if(root->val < max_value && root->val > min_value && (min_max_judge(root->left,min_value,root->val) && min_max_judge(root->right,root->val, max_value)))
            return true;
        else
            return false;
    }

}

(3)通过vector存中序遍历的val,然后从头到尾判断是否满足递增
因为中序遍历所经过的点的值必然是从小到大的(AC)【较快】

class Solution {
public:
    vector<int> oder_vector;  
    bool isValidBST(TreeNode* root) {
        if(root==NULL) return true;
        if(root->left==NULL&&root->right==NULL) return true;
        oder_search(root,oder_vector);
        for(int i=1;i<oder_vector.size();i++)
            if(oder_vector[i] <= oder_vector[i-1]) return false;
        return true;
    }
    void oder_search(TreeNode* root,vector<int>& oder_vector){
        if(root==NULL) return;
        oder_search(root->left,oder_vector);
        oder_vector.push_back(root->val);
        oder_search(root->right,oder_vector);
    }

};

(4)优化(3),改成一种空间复杂度为O(1)的方法(AC)【很快】
每次用pre记录上一个遍历的点,然后比较当前点的val与pre的大小,一旦出现root->val <= pre时候立马退出,快了很多


这里要注意的点就是,如果单纯初始pre=INT_MIN的话,我们并不知道整棵树最左边的点是否比INT_MIN大,万一刚好等于INT_MIN呢就出错了,检测了一下发现,leetcode上面的样例真的有最左边为INT_MIN的,666


所以加了一个判断flag1 = true,第一次过后就变成false,使得pre变成整棵树最左边的值

class Solution {
public:
    bool isValidBST(TreeNode* root) {
        if(root==NULL) return true;
        if(root->left==NULL&&root->right==NULL) return true;
        int flag = 0;
        bool flag1 = true;
        int pre = INT_MIN;
        oder_search(root,flag,pre,flag1);
        if(flag == 1) return false;
        return true;
    }
    void oder_search(TreeNode* root,int & flag,int& pre,bool& flag1){
        if(root==NULL) return;
        oder_search(root->left,flag,pre,flag1);
        if(flag1)
        {
            pre = root->val;
            flag1 = false;
        }
        else
        {
            if(root->val <= pre){
                flag = 1;
                return;
            }
            pre = root->val;
        }


        oder_search(root->right,flag,pre,flag1);
    }

};

python


(1)最大最小值:
python是可以AC的,【慢】
注意
-2**31要减1
2**31不能减1
其实就是为了防止inf的问题啦,你可以试试去掉时通不过的样例

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:  
    def isValidBST(self, root):  
        return self.min_max_search(root,-2**31-1,2**31)#注意测试样例
    def min_max_search(self, root, min, max):
        if root is None:
            return True
        return root.val < max and root.val > min and self.min_max_search(root.left,min,root.val) and self.min_max_search(root.right,root.val,max)

(2)C++方法(4)的python版本啦,一股气写的,有点粗糙(AC)

class Solution(object):

    def oder_search(self,root,flags,pres,flag1s):
        global flag
        global flag1
        global pre
        flag = flags
        flag1 = flag1s
        pre = pres
        if root is None:
            return
        self.oder_search(root.left,flag,pre,flag1)
        if(flag1):
            pre = root.val
            flag1 = False
        else:
            if root.val <= pre:
                flag = 1
                return
        pre = root.val
        self.oder_search(root.right,flag,pre,flag1)

    def isValidBST(self, root):
        global flag
        global flag1
        global pre
        if root is None:
            return True
        if root.left == None and root.right == None:
            return True
        flag = 0
        pre = 0
        flag1 = True
        self.oder_search(root,flag,pre,flag1)
        if flag is 1:
            return False
        return True



        """
        :type root: TreeNode
        :rtype: bool
        """

(3)当然,仔细想想可以将(2)的代码精简一下(AC):

class Solution(object):
    value = None
    def isValidBST(self, root):
        if root is None:
            return True
        ans = self.isValidBST(root.left)
        if(self.value is None):
            self.value = root.val
        else:
            if root.val <= self.value:
                ans = False
            self.value = root.val
        ans = ans and self.isValidBST(root.right)
        return ans 

然后才发现,精简后并不是立马退出,尴尬,哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值