LeetCode99.恢复二叉搜索树
题目
代码
这里学习了老马的思路,点击这里查看原文。
这个题目其实就是在有序序列中交换了两个数字。
交换的位置有两种情况:
- 相邻的两个数字交换
[ 1 2 3 4 5 ] 中 2 和 3 进行交换,[ 1 3 2 4 5 ],这样的话只产生一组逆序的数字(正常情况是从小到大排序,交换后产生了从大到小),3 2。
我们只需要遍历数组,找到后,把这一组的两个数字进行交换即可。
- 不相邻的两个数字交换
[ 1 2 3 4 5 ] 中 2 和 5 进行交换,[ 1 5 3 4 2 ],这样的话其实就是产生了两组逆序的数字对。5 3 和 4 2。
所以我们只需要遍历数组,然后找到这两组逆序对,然后把第一组前一个数字和第二组后一个数字进行交换即完成了还原。
综上,在中序遍历中,只需要利用一个 pre 节点和当前节点比较,如果 pre 节点的值大于当前节点的值,那么就是我们要找的逆序的数字。分别用两个指针 first 和 second 保存即可。如果找到第二组逆序的数字,我们就把 second 更新为当前节点。最后把 first 和 second 两个的数字交换即可。
/**
* Definition for a binary tree node.
* public class TreeNode {
* public int val;
* public TreeNode left;
* public TreeNode right;
* public TreeNode(int x) { val = x; }
* }
*/
public class Solution
{
private TreeNode pre = null;
private TreeNode first = null;
private TreeNode second = null;
public void RecoverTree(TreeNode root)
{
inorderTraversal(root);
if (first == null || second == null)
return;
int temp = first.val;
first.val = second.val;
second.val = temp;
}
private void inorderTraversal(TreeNode root)
{
if (root == null)
return;
inorderTraversal(root.left);
if (pre != null && pre.val > root.val)
{
if (first == null)
{
first = pre;
second = root;
}
else
second = root;
}
else
pre = root;
inorderTraversal(root.right);
}
}