- 恢复二叉搜索树
Difficulty: 困难
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例 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
进阶:
- 使用 O(n) 空间复杂度的解法很容易实现。
- 你能想出一个只使用常数空间的解决方案吗?
Solution
Language: 全部题目
1.迭代
// 对于树的解决方案,基本是都是在做遍历的时候 进行数据操作。因此,本题采用中序遍历。
// 中序遍历是一个有序的 左中右。 那么对于一个无序的 需要我们修改的中序结果为 3,1,null,null,2
// 可以分析到 3 1 是我们交换的位置,
// 1.找到第一个 既 第一个大于后一个的值即为 firstNode
// 2.第二个 在找到第一个的前提下,前一个大于后一个。即为secondNode
// 好了,我们来分析一下时间复杂度 即为O(n) 只需要遍历一遍树即可。
public void recoverTree(TreeNode root) {
if(root == null) return;
TreeNode p1 = null;
TreeNode p2 = null;
TreeNode p = new TreeNode(Integer.MIN_VALUE);
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while(cur != null || !stack.isEmpty()){
while(cur != null){
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
//找到第一个节点
if(p1 == null && p.val > cur.val) p1 = p;
//找到第二个节点
if(p1 != null && p.val > cur.val) p2 = cur;
p = cur;
cur = cur.right;
}
int tmp = p1.val;
p1.val = p2.val;
p2.val = tmp;
}
2.递归
TreeNode p1 = null;
TreeNode p2 = null;
TreeNode p = new TreeNode(Integer.MIN_VALUE);
public void recoverTree(TreeNode root) {
in_order(root);
int t = p1.val;
p1.val = p2.val;
p2.val = t;
}
public void in_order(TreeNode r){
if(r == null) return;
in_order(r.left);
if(p1 == null && p.val > r.val) p1 = p;
if(p1 != null && p.val > r.val) p2 = r;
p = r;
in_order(r.right);
}