题目
给你二叉搜索树的根节点 root
,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入:root = [1,3,null,null,2]
输出:[3,1,null,null,2]
解释:3 不能是 1 的左孩子,因为 3 > 1 。交换 1 和 3 使二叉搜索树有效。
1
2
3
2
3
示例 2:
输入:root = [3,1,4,null,null,2]
输出:[2,1,4,null,null,3]
解释:2 不能在 3 的右子树中,因为 2 < 3 。交换 2 和 3 使二叉搜索树有效。
1
2
3
2
3
提示:
- 树上节点的数目在范围
[2, 1000]
内 -2
31<= Node.val <= 2
31- 1
进阶: 使用 O(n)
空间复杂度的解法很容易实现。你能想出一个只使用 O(1)
空间的解决方案吗?
题解
java
public void recoverTree(TreeNode root) {
List<TreeNode> list = new ArrayList<>();
// 中序遍历树
Consumer<TreeNode> inorderTraversal = new Consumer<TreeNode>() {
@Override
public void accept(TreeNode node) {
if (node == null) {
return;
}
this.accept(node.left);
list.add(node);
this.accept(node.right);
}
};
inorderTraversal.accept(root);
TreeNode first = null, second = null;
// 找到中序遍历节点中降序节点
for (int i = 1; i < list.size(); i++) {
if (list.get(i).val < list.get(i - 1).val) {
if (first == null) {
// 第一个降序
first = list.get(i - 1);
second = list.get(i);
} else {
// 第二个降序
second = list.get(i);
}
}
}
// 交换节点值
first.val ^= second.val;
second.val ^= first.val;
first.val ^= second.val;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36