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 

然後才發現,精簡後並不是立馬退出,尷尬,哈哈

發佈了45 篇原創文章 · 獲贊 18 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章