[leetcode] 99. 恢复二叉搜索树

99. 恢复二叉搜索树

一开始想了好久没有什么好思路,去网上搜了一下,原来是中序遍历。

二叉搜索树的中序遍历是个(递增)有序数列,利用这个特性,我们可以很巧妙的解决这个题。

先看第二个例子,中序遍历后是:13245,观察发现只有一处发生了降序,只在第二位与第三位发生了降序情况,说明这两个数为异常数,交换3和2的位置重新中序遍历:12345

第一个例子,中序遍历是:321,观察发现有两处发生了降序,第一到第二位,以及第二到第三位,这种情况下交换第一位与第三位即可

实际上题目中只有两个节点被交换了,所以降序情况最多也只会出现两处。所以分两种情况处理即可。

我们再造个例子,看的更直观点:

[10 17 15 1 8 12 5]

中序遍历

1 17 8 10 12 15 5

17与3发生了降序,15与5发生了降序,我们将第一个降序的前一个元素与第二个降序的后一个元素,进行交换即可。

当只有一次降序出现时(可以理解为两个降序挤到了一块嘛),降序的前一个元素与降序的后一个元素,进行交换即可。

代码

class Solution {
    TreeNode p, q, last;

    void middle(TreeNode root) {
        if (root == null) return;
        middle(root.left);
        if (last != null && last.val > root.val) {
            if (p == null) p = last;
            q = root;
        }
        last = root;
        middle(root.right);
    }

    public void recoverTree(TreeNode root) {
        middle(root);
        int tmp = p.val;
        p.val = q.val;
        q.val = tmp;
    }
}
posted @ 2018-11-04 23:51 ACBingo 阅读(...) 评论(...) 编辑 收藏