leetcode 99. Recover Binary Search Tree

思路很简单,因为只有两个节点互换了,只需要找到这两个节点,再换回来即可

可是怎么找到这两个节点呢?

方法一

直接中序遍历得到一个数组arr1,然后新建一个数组arr2,copy arr1,将其排序

对比arr1和arr2,很容易就能找到不同的两个节点,互换即可

时间复杂度为o(nlogn)

class Solution {
    public void recoverTree(TreeNode root) {
        List<Integer> sorted = new ArrayList<>();
        inorder(root, sorted);
        List<Integer> tmp = new ArrayList<>(sorted);
        Collections.sort(tmp);
        int[] pair = new int[2];
        int count = 0;
        for(int i=0; i<sorted.size(); i++){
            if(sorted.get(i) != tmp.get(i)){
                pair[count++] = sorted.get(i);
            }
        }
        
        dfs(root, pair);
    }
    private void inorder(TreeNode root, List<Integer> sorted){
        if(root == null)
            return;
        inorder(root.left, sorted);
        sorted.add(root.val);
        inorder(root.right, sorted);
    }
    private void dfs(TreeNode root, int[] tmp){
        if(root == null)
            return;
        if(root.val == tmp[0]){
            root.val = tmp[1];
        }else if(root.val == tmp[1])
            root.val = tmp[0];
        dfs(root.left, tmp);
        dfs(root.right, tmp);
        
    }
}

方法二

只用一个中序遍历,first记录第一个错误节点,second同理

第一个出错的节点,肯定是他的值比后一个节点的值大

第二个出错的节点,肯定是它的值比前一个节点的值小

按照这个规律,就可以找到这两个出错的节点

class Solution {
    TreeNode first = null;
    TreeNode second = null;
    TreeNode prev = new TreeNode(Integer.MIN_VALUE);
    
    
    public void recoverTree(TreeNode root) {
        inorder(root);
        int tmp = first.val;
        first.val = second.val;
        second.val = tmp;
    }
    private void inorder(TreeNode root){
        if(root == null)
            return;
        inorder(root.left);
        if(first == null && prev.val > root.val){
            first = prev;
        }
        if(first != null && prev.val > root.val){
            second = root;
        }
        prev = root;
        
        inorder(root.right);
        
    }
    
}
原文地址:https://www.cnblogs.com/hwd9654/p/11374914.html