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;
    }

    运行结果:

      

  • 相关阅读:
    1)①爬取中国新闻网科技相关部分新闻
    摘记
    KNN算法[分类算法]
    Naive Bayes(朴素贝叶斯算法)[分类算法]
    Oracle 隔离级别
    解决问题没必要过于纠结于原理
    Oracle DBMS_METADATA.GET_DDL
    【听海日志】之ORACLE物化视图 [转]http://www.itpub.net/thread-1614812-1-1.html
    oracle 12c 基础
    Postgres查看数据库中的表及表中字段和类型
  • 原文地址:https://www.cnblogs.com/zz-zhang/p/12312897.html
Copyright © 2011-2022 走看看