【1】【leetcode-99】 恢复二叉搜索树

(没思路)

99. 恢复二叉搜索树

二叉搜索树中的两个节点被错误地交换。

请在不改变其结构的情况下,恢复这棵树。

示例 1:

输入: [1,3,null,null,2]

   1
  /
 3
  
   2

输出: [3,1,null,null,2]

   3
  /
 1
  
   2

示例 2:

输入: [3,1,4,null,null,2]

  3
 / 
1   4
   /
  2

输出: [2,1,4,null,null,3]

  2
 / 
1   4
   /
  3

进阶:

  • 使用 O(n) 空间复杂度的解法很容易实现。
  • 你能想出一个只使用常数空间的解决方案吗?

中序遍历,正常情况下为升序排列,结果中如果有一个降序对,说明该两个node需交换;若有两个降序对,说明第一对的前一个node和第二对的后一个node需要交换。

所谓简单的O(n)个空间的思路:
        中序遍历得到数组,比如[1,3,2,4],在用一个hashmap<int,TreeNode>保存对象.
        然后对数组排序,得到[1,2,3,4],对比得到2和3两个节点不一样,交换一下值即可。
 下面实现进阶的常数空间思想:
        在纸上写几个数组观察一下,可以发现,只需要找到三个结点(prev_first,first,second),就能进行交换,且只交换值是最方便的。
        中序遍历,寻找第一个递减的节点,用prev记录前一个节点。
        prev_first记录frist前驱,first记录现在。
        再次寻找第二个递减的节点,second记录。若是找到了second,交换prev_first和second,若是没找到,交换prev_first和first
链接:https://www.nowcoder.com/questionTerminal/67c7172122b54b748e78eac7b183b5f3
来源:牛客网

public class Solution {
    private TreeNode firstErrorNode=null;
    private TreeNode secondErrorNode=null;
    private TreeNode lastNode=null;
    public void recoverTree(TreeNode root){
        dealCore(root);
        int temp=secondErrorNode.val;
        secondErrorNode.val=firstErrorNode.val;
        firstErrorNode.val=temp;
    }
    private void dealCore(TreeNode root){
        if(root==null)return;
        dealCore(root.left);
        if(lastNode!=null){
            if(lastNode.val>root.val){
                if(firstErrorNode==null){
                    firstErrorNode=lastNode;
                }
                secondErrorNode=root;
            }
        }
        lastNode=root;
        dealCore(root.right);
    }
}

看了思路:

public class RecoverTree {
    TreeNode firstError = null;
    TreeNode lastNode = null;
    TreeNode secondError = null;
    public void recoverTree(TreeNode root) {
        inOrder(root);
        int temp = firstError.val;
        firstError.val = secondError.val;
        secondError.val = temp;
    }

    public void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        if (lastNode != null) {
            if (lastNode.val > root.val) {
                if (firstError == null) {
                    firstError = lastNode;
                }
                secondError = root;
            }
        }
        lastNode = root;
        inOrder(root.right);
    }
}