题目:
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
理解题目:
意思就是说给的二叉搜索树中有两个结点是被交换的,我们要做的就是把这两个找到,然后对他们进行交换。
思路:
二叉搜索树的中序遍历是一个递增的序列,但是,因为被错误交换了两个结点,所以这个中序序列有两个值我们要将它找出来,然后将它们交换就可以。
子问题:如何得到中序序列
- 可以通过递归算法
- 可以通过Morris 算法(即线索二叉树)
子问题:如何找到这两个被错误交换的结点
- 两个被交换的结点是相邻的
- 两个被交换的不是相邻的
子问题:如何在树中交换两个结点的值。
public void recoverTree(TreeNode root) {
if (root == null)
return;
List<Integer> list = new LinkedList<>();
inorder(root, list);
int x = -1;
int y = -1;
for (int i = 0; i < list.size() - 1; i++) {
if (list.get(i) > list.get(i + 1)) {
if (x == -1)
x = list.get(i);
y = list.get(i + 1);
}
}
swap(root, x, y);
}
private void swap(TreeNode root, int x, int y) {
if (root != null && (root.val == x || root.val == y))
root.val = root.val == x ? y : x;
swap(root.left, x, y);
swap(root.right, x, y);
}
public void inorder(TreeNode root, List<Integer> list) {
if (root == null)
return;
inorder(root.left, list);
list.add(root.val);
inorder(root.right, list);
}