zoukankan      html  css  js  c++  java
  • 99. Recover Binary Search Tree (Tree; DFS)

    Two elements of a binary search tree (BST) are swapped by mistake.

    Recover the tree without changing its structure.

    Note:
    A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

     
    法I:BST的中序遍历结果是递增序列。把这个递增序列存储到数组中,再遍历一遍数组,便可知道swap的两个元素
    class Solution {
    public:
        void recoverTree(TreeNode *root) {
            vals.clear();
            treeNodes.clear();
            inorderTraverse(root);
            
            sort(vals.begin(), vals.end());
            for (int i = 0; i < treeNodes.size(); ++i)
            {
                treeNodes[i]->val = vals[i]; //只改变值,不改结构
            }
        }
        
        void inorderTraverse(TreeNode* root)
        {
            if (!root)
                return;
            
            inorderTraverse(root->left);
            vals.push_back(root->val);
            treeNodes.push_back(root);
            inorderTraverse(root->right);        
        }
    private:
        vector<int> vals;  
        vector<TreeNode*> treeNodes;  
    };
    空间复杂度O(1)的解决方案:在中序遍历的时候,当第一次扫描到前一个节点>后一个节点,那么前一个节点必定错了;它要么就是和后一个节点交换,要么是和第二次扫描到前一个节点>后一个节点时的后一个节点交换。
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        void recoverTree(TreeNode* root) {
            TreeNode* pre = NULL; //当前访问节点的上一个节点
            TreeNode* swap1 = NULL;
            TreeNode* swap2 = NULL;
            inOrderTraverse(root,pre,swap1,swap2);
            
            int tmp = swap1->val;
            swap1->val = swap2->val;
            swap2->val = tmp;
        }
        
        void inOrderTraverse(TreeNode* root, TreeNode* &pre,TreeNode* &swap1,TreeNode* &swap2){ //important to use &, otherwise new object will use a new address and the result won't bring back to caller
            
            //visit left child
            if(root->left) inOrderTraverse(root->left,pre,swap1,swap2);
    
            //visit root
            if(pre && root->val < pre->val){
                swap2 = root;
                if(swap1==NULL) {
                    swap1 = pre;
                }
            }
            pre = root;
            
            //visit right child
            if(root->right) inOrderTraverse(root->right,pre,swap1,swap2);
        }
    };

  • 相关阅读:
    springMVC必须的jar包
    project---clean
    maven项目 启动报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
    @ResponseBody 注解
    HttpServletRequest 需要导入xx包?
    Maven中GroupID和ArtifactID
    Java中包、类、方法、属性、常量的命名规则
    使用 @RequestMapping 注解,需要导入的包:spring-webmvc
    【杂题】【动态规划】【搜索】——洛谷P1441砝码称重
    搞清clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop
  • 原文地址:https://www.cnblogs.com/qionglouyuyu/p/4854218.html
Copyright © 2011-2022 走看看