题目描述
二叉搜索树中的两个节点被错误地交换;请在不改变其结构的情况下,恢复这棵树;
示例 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
进阶:
1.使用 O(n) 空间复杂度的解法很容易实现;
2.你能想出一个只使用常数空间的解决方案吗?
解题思路
二叉搜索树的中序遍历就是一个递增的序列,所以可以根据这个序列是否递增来判断其是否是二叉搜索树;
当然,对于本题,可以这样解:
1.通过中序遍历,将遍历结果放在一个ArrayList中;
2.双指针,从头尾向中间靠;
import java.util.ArrayList;
public class Solution099 {
private class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public void recoverTree(TreeNode root) {
ArrayList<TreeNode> path = new ArrayList<TreeNode>();
//中序遍历,获得这个二叉搜索树的遍历序列
dfs(root, path);
int start = 0, end = path.size() - 1;
while (start < end) { //注意是<
if (path.get(start).val < path.get(start + 1).val) {
start++;
} else if (path.get(end).val > path.get(end - 1).val) {
end--;
} else {
//找到错误的节点,交换回来,只交换val
int tmp = path.get(end).val;
path.get(end).val = path.get(start).val;
path.get(start).val = tmp;
return;
}
}
}
//中序遍历,获得这个二叉搜索树的遍历序列
private void dfs(TreeNode node, ArrayList<TreeNode> path) {
if (node == null) {
return;
}
dfs(node.left, path);
path.add(node); //将该节点加入path
dfs(node.right,path);
}
}