Recover Binary Search Tree

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.

思路:

  中序遍历的变形

我的代码:

public class Solution {
    public void recoverTree(TreeNode root) {
        if(root == null)    return;
        List<TreeNode> list = new ArrayList<TreeNode>();
        inorderTree(root, list);
        TreeNode left = null;
        TreeNode right = null;
        for(int i = 0; i < list.size() -1; i++)
        {
            TreeNode one = list.get(i);
            TreeNode two = list.get(i+1);
            if(one.val > two.val)
            {
                if(left == null)
                {
                    left = one;
                    right = two;
                }
                else
                {
                    right = two;
                }
            }
        }
        if(left != null && right != null)
        {
            int tmp = left.val;
            left.val = right.val;
            right.val = tmp;
        }
    }
    public void inorderTree(TreeNode root, List<TreeNode> list)
    {
        if(root == null)    return;
        if(root.left == null && root.right == null)
        {
            list.add(root);
            return;
        }
        inorderTree(root.left, list);
        list.add(root);
        inorderTree(root.right, list);
    }
}
View Code

他人代码1:

public class RecoverTree {
    TreeNode pre = null;
    TreeNode first = null;
    TreeNode second = null;
    
    
    public void recoverTree(TreeNode root) {
        inOrder(root);
        
        // swap the value of first and second node.
        int tmp = first.val;
        first.val = second.val;
        second.val = tmp;
    }
    
    public void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        
        // inorder traverse.
        inOrder(root.left);
        // 判断 pre 是否已经设置
        if (pre != null && pre.val > root.val) {
            if (first == null) {
                // 首次找到反序.
                first = pre;
                second = root;
            } else {
                // 第二次找到反序,更新Second.
                second = root;
            }
        }

        pre = root;

        // inorder traverse.
        inOrder(root.right);
    }
View Code

他人代码2:

public void recoverTree1(TreeNode root) {
        if (root == null) {
            return;
        }
        
        TreeNode node1 = null;
        TreeNode node2 = null;
        
        TreeNode pre = null; 
        
        Stack<TreeNode> s = new Stack<TreeNode>();
        TreeNode cur = root;
        
        while (true) {
            while (cur != null) {
                s.push(cur);
                cur = cur.left;
            }
            
            if (s.isEmpty()) {
                break;
            }
            
            TreeNode node = s.pop();
            
            if (pre != null) {
                // invalid order
                if (pre.val > node.val) {
                    if (node1 == null) {
                        node1 = pre;
                        node2 = node;
                    } else {
                        node2 = node;
                    }
                }
            }
            
            pre = node;
            
            cur = node.right;
        }
        
        int tmp = node1.val;
        node1.val = node2.val;
        node2.val = tmp;
        
        return;
    }
View Code

学习之处:

  • 我的代码的空间复杂度为O(n)
  • 他人代码1的空间复杂度为O(lgn) 他人代码的空间复杂度为O(lgn),需要注意的是他人代码2中是中序遍历的非递归算法,需要注意,之前judging了好几次才AC。
原文地址:https://www.cnblogs.com/sunshisonghit/p/4344525.html