• leetcode--Recover Binary Search Tree


    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?

    confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.


    OJ's Binary Tree Serialization:

    The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

    Here's an example:

       1
      / 
     2   3
        /
       4
        
         5
    

    The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".


    题意:某排序二叉树的两个节点交换了位置,请找出这两个节点。而且将交换这两个节点的值。从而恢复排序二叉树。

    要求使用常数空间。

    分类:二叉树


    解法1:题目要求仅仅能使用常数空间,我们自然会想到使用递归遍历。而不是非递归。

    因为排序二叉树的中序遍历。能够得到这个从小到大排序的数组,我们能够使用这个性质。在中序遍历过程中。发现某个节点不按顺序。就标记下来。

    可是顺序错误是须要跟之前的节点比較大小的,所以在递归过程中,我们要保留当前节点的前一个节点的指针(指按中序遍历顺序的前后)。

    这时有两种情况,一种是前后两个节点交换了位置(指按中序遍历顺序的前后)。这时我们仅仅能找到一个位置错误。

    由于比如对于顺序{1,3,2,4},3,2换了位置,可是仅仅有当pre指向3,cur指向2的时候比較,才回发现位置异常,其它情况没有,也就是说仅仅出现一次位置异常。

    这样的情况。我们交换这两个节点就能够了。


    对于另外一种情况。就是两个节点距离较远,比如{1,6,3,4,5,2}

    这时对于{6,3}会发生一次异常,{5,2}会发生一次异常,我们应该保留第一次异常的pre。保留第二次异常的cur

    然后再交换这两个节点的值。


    以下来看代码:

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    public class Solution {
        TreeNode pre = null;
        TreeNode mistake1,mistake2;
        
        public void recoverTree(TreeNode root) {
            inorder(root);  
            if(mistake1!=null&&mistake2!=null) {  
                int tmp = mistake1.val;  
                mistake1.val = mistake2.val;  
                mistake2.val = tmp;  
            }  
        }
        /**
         * 对于BST而言。中序遍历以后是从小到大排序的
         * 中序遍历递归算法,每次保留前一个的指针,用于比較 
         */
        public void inorder(TreeNode root){
            if(root==null) return;
            if(root.left!=null){//先訪问左子树
                inorder(root.left);
            }
            if(pre!=null&&root.val<pre.val) {//假设pre不为空(第一个訪问的节点,pre为空),而且顺序不正确  
                if(mistake1==null) {//假设一个错误都没出现。将相邻的两个节点标记  
                    mistake1 = pre;  
                    mistake2 = root;  
                } else {//假设出现第二次错误,更新  
                    mistake2 = root;  
                }  
            }  
            pre = root;//将当前节点标记为右子树的前节点  
            if(root.right!=null) {//訪问右子树  
                inorder(root.right);  
            }  
        }
    }


  • 相关阅读:
    什么是二进制补码
    第四章 VB程序的控制结构
    第三章 VB的程序设计基础
    C#學習基礎方法
    C#學習基礎繼承
    C#學習基礎變量和常量
    C#學習基礎域和屬性
    第八章 VB中ActiveX控件的使用
    写给WEB2.0的站长 不仅仅是泼冷水(转)
    常见错误和难点分析
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6859765.html
Copyright © 2020-2023  润新知