码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode--Recover Binary Search Tree

时间:2015-08-01 11:34:59      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:leetcode   算法   数据结构   

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


版权声明:本文为博主原创文章,未经博主允许不得转载。

leetcode--Recover Binary Search Tree

标签:leetcode   算法   数据结构   

原文地址:http://blog.csdn.net/crazy__chen/article/details/47184139

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!