99.恢复二叉搜索树

99.恢复二叉搜索树

image-20200808201051795

题解

前序可以很方便地形成一条搜索路径,
中序遍历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;
    }
}

猜你喜欢

转载自blog.csdn.net/Rush6666/article/details/107885377
今日推荐