99.恢复二叉搜索树
题解
前序可以很方便地形成一条搜索路径,
中序遍历BST的时候可以得到一个有序序列,
后序可以用来计算一颗算数表达式树
运用空间复杂度O(1)的Morris算法进行中序遍历(本题与二叉树顺序相关,使用中序遍历),先找到当前节点左子树的最右的节点(即前驱节点,中序遍历的最后一个节点),
- 如果前驱节点为空,将其右节点指向当前节点
- 如果前驱节点不为空,说明前驱节点已经指向当前节点,说明我们已经遍历完了当前节点的左子树,我们必须将前驱节点的右节点置空(只是利用这个节点暂存数据,起到类似栈的效果),然后访问当前节点的右节点。(x = x.right)
重复上述操作直至遍历整棵树即可。
class Solution {
public void recoverTree(TreeNode root) {
TreeNode first = null, last = null;
TreeNode pre = null, cur = root, tail = null;
while (cur != null) {
// 模板代码,和遍历相同
tail = cur.left;
if (tail != null) {
// 找到 tail 位置
while (tail.right != null && tail.right != cur) {
tail = tail.right;
}
if (tail.right == null) {
// 暂时链接,充当栈的作用
tail.right = cur;
cur = cur.left;
continue;
} else {
// 断开链接,保证二叉树结构不变
tail.right = null;
}
}
// 更新 first & last 节点
if (pre != null && pre.val > cur.val) {
last = cur;
if (first == null) {
first = pre;
}
}
// 更新 pre & cur 节点
pre = cur;
cur = cur.right;
}
// 交换
int temp;
temp = first.val;
first.val = last.val;
last.val = temp;
}
}