• Recover Binary Search Tree


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

    Recover the tree without changing its structure.

    Ref:http://fisherlei.blogspot.com/2012/12/leetcode-recover-binary-search-tree.html

    O(1)的解法就是
    Inorder traverse, keep the previous tree node,
    Find first misplaced node by
    if ( current.val < prev.val )
       Node first = prev;

    Find second by
    if ( current.val < prev.val )
       Node second = current;

    After traversal, swap the values of first and second node. Only need two pointers, prev and current node. O(1) space.

    但是这个解法的前提是Traverse Tree without Stack. 中序遍历如何才能不使用栈。这里就要引入一个概念, Threaded Binary Tree。So, we first create links to Inorder successor and print the data using these links, and finally revert the changes to restore original tree.

    1. Initialize current as root 
    2. While current is not NULL
       If current does not have left child
          a) Print current’s data
          b) Go to the right, i.e., current = current->right
       Else
          a) Make current as right child of the rightmost node in current's left subtree
          b) Go to this left child, i.e., current = current->left
    public class Solution {
        public void recoverTree(TreeNode root) {
            TreeNode f1 = null, f2 = null;
            TreeNode current, pre, parent = null;
    
           if(root == null)
                 return;
           // 用来记录是第几次找到bad node, 因为第一次找到的bad node为cur.pre,第二次找到bad node是cur
           boolean found = false;
           current = root;
           while(current != null)
           {                
                 if(current.left == null)
                 {
                        if(parent != null && parent.val > current.val)
                        {
                               if(!found)
                               {
                                     f1 = parent;
                                     found = true;
                               }
                               f2 = current;
                        }
                        parent = current;
                        current = current.right;     
                 }   
                 else
                 {
                        /* Find the inorder predecessor of current */
                        pre = current.left;
                        while(pre.right != null && pre.right != current)
                               pre = pre.right;
    
                        /* Make current as right child of its inorder predecessor */
                        if(pre.right == null)
                        {
                               pre.right = current;
                               current = current.left;
                        }
    
                        /* Revert the changes made in if part to restore the original
                        tree i.e., fix the right child of predecssor */  
                        else
                        {
                          // 注意跳进这里的原因是,当把root 设为左子树的最右节点时,root.left 仍然为左子树的根节点,相当于生成了一个环
                               pre.right = null;
                               if(parent.val > current.val)
                               {
                                     if(!found)
                                     {
                                            f1 = parent;       
                                            found = true;
                                     }
                                     // f2 不写在else里的原因是 有可能是相邻的两个元素交换了
                                     f2 = current;
                               }
                               parent = current;
                               current = current.right;     
                        } /* End of if condition pre->right == NULL */
                 } /* End of if condition current->left == NULL*/
           } /* End of while */
    
           if(f1 != null && f2 != null){
               int tmp = f1.val;
               f1.val = f2.val;
               f2.val = tmp;
           }
                 
        }
    }        
    /**
     * Definition for binary tree
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public static void recoverTree(TreeNode root) {
            ArrayList<TreeNode> inorderList = new ArrayList<TreeNode>();
            inorder(root, inorderList);
            int first= -1, second  = -1; 
            boolean secondNumber = false;
            for(int i = 1; i < inorderList.size();i++){
                if (inorderList.get(i-1).val > inorderList.get(i).val){
                    if(!secondNumber){
                        first = i-1;
                        second = i;
                        secondNumber = true;
                    }else{
                        second = i;
                    }
                }
            }
            swap(inorderList.get(first), inorderList.get(second));
        }
        
        private static void inorder(TreeNode root, ArrayList<TreeNode> inorderList){
            if(root != null){
                inorder(root.left, inorderList);
                inorderList.add(root);
                inorder(root.right, inorderList);
            }
        }
        
        private static void swap(TreeNode i, TreeNode j){
            int tmp = i.val;
            i.val = j.val;
            j.val = tmp;
        }
        
    }
  • 相关阅读:
    【leetcode】13. Roman to Integer
    【leetcode】12. Integer to Roman
    【leetcode】11. Container With Most Water
    Linux 学习总结(五)-linux 文件系统及相关命令
    Linux学习总结(四)-两种模式修复系统,单用户,救援模式
    Linux学习总结(三)之 putty,xshell远程连接及密钥认证篇
    Linux学习总结(二) 网络配置-NAT方式静态IP配置篇
    Linux学习总结(一) windos环境vmware安装centos7
    看完这篇Linux基本的操作就会了
    linux下tar命令详解
  • 原文地址:https://www.cnblogs.com/RazerLu/p/3557776.html
Copyright © 2020-2023  润新知