Thursday, April 2, 2015

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?
Solution:
因为在BST中,中序遍历是有序的。所以如果有元素被调换了,则中序遍历中必然出现逆序的情况。
分两种考虑,1. 如果是中序遍历相邻的两个元素被调换了,只会出现一次逆序的情况,只需要把这个两个节点记录下来最后调换值就可以;
2. 如果是不相邻的两个元素被调换,会发生两次逆序的情况,需要调换的元素应该是第一次逆序前面的元素,和第二次逆序后面的元素。比如1234567,1和5调换了,会得到5234167,逆序发生在52和41,所以是52的第一个元素,和41的第二个元素调换即可。
中序遍历寻找逆序情况,调换的第一个元素,是第一个逆序的第一个元素,调换的第二个元素如果只有一次逆序,则是那一次的后一个,如果有两次逆序则是第二次的后一个。
一次中序遍历,时间复杂度是O(n),空间是栈大小O(logn)
/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void recoverTree(TreeNode root) {
        if(root == null)
            return;
        
        ArrayList pre = new ArrayList();
        ArrayList res = new ArrayList();
        pre.add(null);
        helper(root, pre, res);
        if(res.size() != 0) {
            int temp = res.get(0).val;
            res.get(0).val = res.get(1).val;
            res.get(1).val = temp;
        }
    }
    
    public void helper(TreeNode root, ArrayList pre, ArrayList res) {
        if(root == null) {
            return;
        }
        
        helper(root.left, pre, res);
        if(pre.get(0) != null && pre.get(0).val > root.val) {
            if(res.size() == 0) {
                res.add(pre.get(0));
                res.add(root);
            }else {
                res.set(1, root);
            }
        }
        pre.set(0, root);
        helper(root.right, pre, res);
    }
}

Reference: http://blog.csdn.net/linhuanmars/article/details/24566995

No comments:

Post a Comment