• 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.

    思路:

    首先需要理解的是,不是当前左右节点的数值小于当前根节点就行,而是左子树所有的节点数值均小于根节点才可以。

    最简单的方法就是递归判断左右子树的满足条件,对于第一个根节点,对于左子树,看下面所有的节点是否满足小于根节点数值,对于右子树,看下面所有节点是否满足所有节点大于根节点数值。

    然后循环递归。

    接下来两个解法是中序遍历。

    最后一个是一个变型的中序遍历,但里面牵涉到为啥指向右边子树的问题,这是因为每次比较已经比较了左边的,而左子树的某一个下属节点的右子树却未必。

    代码:

    class Solution {
    public:
        bool isValidBST(TreeNode* root) {
            if(root==NULL)  return true;
            
            return isSubTreeGreater(root->left,root->val)&&isSubTreeLess(root->right,root->val)
                    &&isValidBST(root->left)&&isValidBST(root->right);
                    //不是左节点小于根节点,右节点大于根节点即可,而是左子树所有节点全部小于当前根节点。对右子树一样。
                    //前面的两个函数是不断检测下面的节点的数值小于当前root顶点值。这能够保证下面的节点全部符合条件
                    //然后通过下面两个函数判断下面左右子树节点
        }
        
        bool isSubTreeGreater(TreeNode* root,int val){
            if(root==NULL)  return true;
            
            return root->val<val&&isSubTreeGreater(root->left,val)&&isSubTreeGreater( root->right,val);
        }
        
        bool isSubTreeLess(TreeNode* root,int val){
            if(root==NULL)  return true;
            
            return root->val>val&&isSubTreeLess(root->left,val)&&isSubTreeLess( root->right,val);
        }
    
    };
    /*
        class Solution2 {
        public:
            int ok=true,first=true;
            bool isValidBST(TreeNode* root) {
                int prev;
                travel(root,prev);
                return ok;
            }
        
            void travel(TreeNode* root,int &prev){
                if(root==NULL)  return;
                if(root->left)  travel(root->left,prev);
                
                int mid=root->val;
                if(!first){
                    if(mid<=prev)   ok=false;
                    prev=mid;//mid 成为过去式
                }else{
                    prev=mid;
                    first=false;
                }
                
                if(root->right) travel(root->right,prev);
            }
        };
        
        class Solution3 {
        public:
            bool isValidBST(TreeNode* root){
                if(root==NULL||(root->left==NULL&&root->right==NULL))   return true;
                
                stack<TreeNode*>st;
                int prev=INT_MIN;
                bool first=true;
                
                while(!st.empty()||root!=NULL){
                    if(root!=NULL){
                        st.push(root);
                        root=root->left;
                    }else{
                        root=st.top();st.pop();
                        if(first||root->val>prev){
                            first=false;
                            prev=root->val;
                        }else{
                            return false;
                        }
                        root=root->right;
                    }
                }
                
                return true;
            }
        };
        
        class Solution4 {
    public:
        bool isValidBST(TreeNode* root) {
            if(!root)  return true;
    
            if(root->left) {
                TreeNode* l = root->left;
                while(l){
                    if(l->val >= root->val) return false;
                    l = l->right;//为什么指向右边,这是因为,在每一次最下面递归调用函数的时候,都已经比较了一次当前
                                 //节点与root值得大小,下面同理。
                }
            }
    
            if(root->right){
                TreeNode* r = root->right;
                while(r) {
                    if(r->val <= root->val) return false;
                    r = r->left;
                }
            }
    
            return isValidBST(root->left)&&isValidBST(root->right);
        }
    };
    */


  • 相关阅读:
    Linux常用的命令
    Docker编写镜像 发布个人网站
    Linux安装docker笔记
    单例模式
    Cache一致性协议之MESI
    linux环境搭建单机kafka
    【Ray Tracing The Next Week 超详解】 光线追踪2-4 Perlin noise
    【Ray Tracing The Next Week 超详解】 光线追踪2-3
    【Ray Tracing The Next Week 超详解】 光线追踪2-2
    【Ray Tracing The Next Week 超详解】 光线追踪2-1
  • 原文地址:https://www.cnblogs.com/jsrgfjz/p/8519847.html
Copyright © 2020-2023  润新知