zoukankan      html  css  js  c++  java
  • 验证二叉搜索树(lc98)、恢复二叉搜索树(lc99)

    二叉搜索树

      二叉搜索树是这样的二叉树,树中所有结点满足:左子树所有结点值小于根结点,右子树所有结点值大于根结点。

    验证方法

      首先想到的是使用递归方法,如果满足前驱结点 < 根结点 < 后继结点,那么继续向下分别对左右子树进行递归,直到有不满足的情况出现,则返回false。还有一种递归想法(参考题解)是为每个子树设置(low, upper),判断根节点值root是否在区间内,然后对左右子树递归判断,左子树区间设置为(low,root-1),右子树为(root+1,upper),并且该方法可以很容易转化为栈实现,具体参考https://leetcode-cn.com/problems/validate-binary-search-tree/solution/yan-zheng-er-cha-sou-suo-shu-by-leetcode/

      下面是第一种递归算法实现

    bool isValidBST(TreeNode* root) {
            if(root == NULL) return true;
            TreeNode* pre = root->left;
            TreeNode* follow = root->right;
            if(pre == NULL && follow == NULL) 
                return true;
            if(pre == NULL){
                while(follow->left) follow = follow->left;
                if(isValidBST(root->right) && root->val < follow->val)
                    return true;
                return false;
            }
            if(follow == NULL){
                while(pre->right) pre = pre->right;
                if(isValidBST(root->left) && root->val > pre->val)
                    return true;
                return false;
            }
            while(follow->left) follow = follow->left;
            while(pre->right) pre = pre->right;
            if(isValidBST(root->left) && isValidBST(root->right) && root->val < follow->val && root->val > pre->val)
                return true;
            return false;
    }

      还有一种常见的方法是对二叉树进行中序遍历,根据搜索树的性质可知,中序遍历的序列是递增的。下面使用栈方法进行中序遍历验证二叉搜索树(也可使用递归遍历或莫里斯遍历)。

    bool isValidBST(TreeNode* root) {
            vector<TreeNode*> stk;
            TreeNode* cur = root;
            long before = (long)INT_MIN - 1;
            while(cur != NULL || stk.size() != 0){
                while(cur != NULL){
                    stk.push_back(cur);
                    cur = cur->left;
                }
                cur = stk.back();
                stk.pop_back();
                if(cur->val <= before) return false;
                before = cur->val;
                cur = cur->right;
            }
            return true;
    }

    恢复二叉搜索树

      如果二叉搜索树中有两个节点互换了位置,请恢复它。

      思路:二叉搜索树的中序遍历会得到递增序列,因此在中序遍历的过程中识别非递增的节点,则可以找到那两个节点的位置(即线性时间寻找递增序列中进行交换的两个值),找到后停止遍历,进行恢复。

      下面使用两种中序遍历方式进行恢复,分别是递归实现和栈迭代实现。

    递归方法

    TreeNode* pre = NULL;
    TreeNode* first = NULL;
    TreeNode* second = NULL;
    void recoverTree(TreeNode* root){
            bool isok = false;
            recoverTree(root, isok);
            int t = first->val;
            first->val = second->val;
            second->val = t;
            return;
    }
    
    void recoverTree(TreeNode* root, bool& isok) {
            if(!isok && root){
                recoverTree(root->left,isok);
                if(isok) return;
                if(pre && root->val < pre->val){
                    second = root;
                    if(first) {
                        isok = true;
                        return;
                    }
                    first = pre;
                }
                pre = root;
                recoverTree(root->right,isok);
            }
            return;
    }

    运行结果如图:

     栈方法

    void recoverTree(TreeNode* root) {
            TreeNode* pre = NULL;
            TreeNode *first = NULL;
            TreeNode *second = NULL;
            stack<TreeNode*> stk;
            while(root || stk.size()){
                while(root){
                    stk.push(root);
                    root = root->left;
                }
                root = stk.top();
                stk.pop();
                if(pre && root->val < pre->val){
                    second = root;
                    if(first) 
                        break;
                    first = pre;
                }
                pre = root;
                root = root->right;
            }
            int t = first->val;
            first->val = second->val;
            second->val = t;
            return;
    }

    运行结果:

      

  • 相关阅读:
    Leetcode 811. Subdomain Visit Count
    Leetcode 70. Climbing Stairs
    Leetcode 509. Fibonacci Number
    Leetcode 771. Jewels and Stones
    Leetcode 217. Contains Duplicate
    MYSQL安装第三步报错
    .net 开发WEB程序
    JDK版本问题
    打开ECLIPSE 报failed to load the jni shared library
    ANSI_NULLS SQL语句
  • 原文地址:https://www.cnblogs.com/zz-zhang/p/12312897.html
Copyright © 2011-2022 走看看