LeetCode——恢复二叉搜索树

Posted Shaw_喆宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode——恢复二叉搜索树相关的知识,希望对你有一定的参考价值。

Q:二叉搜索树中的两个节点被错误地交换。请在不改变其结构的情况下,恢复这棵树。

A:
1.中序遍历 根据出现降序的次数 找出两个错误的节点,交换节点值

  • 只出现一次降序 则第一个为降序时较大的,第二个为降序时较小的
  • 出现了两次降序 则第一个为第一次降序时较大的,第二个为第二次降序时较小的
  public void inorder(TreeNode root, List<Integer> nums) {
    if (root == null) return;
    inorder(root.left, nums);
    nums.add(root.val);
    inorder(root.right, nums);
  }

  public int[] findTwoSwapped(List<Integer> nums) {
    int n = nums.size();
    int x = -1, y = -1;
    for(int i = 0; i < n - 1; ++i) {
      if (nums.get(i + 1) < nums.get(i)) {
        y = nums.get(i + 1);
        // first swap occurence
        if (x == -1) x = nums.get(i);
        // second swap occurence
        else break;
      }
    }
    return new int[]{x, y};
  }

  public void recover(TreeNode r, int count, int x, int y) {
    if (r != null) {
      if (r.val == x || r.val == y) {
        r.val = r.val == x ? y : x;
        if (--count == 0) return;
      }
      recover(r.left, count, x, y);
      recover(r.right, count, x, y);
    }
  }

  public void recoverTree(TreeNode root) {
    List<Integer> nums = new ArrayList();
    inorder(root, nums);
    int[] swapped = findTwoSwapped(nums);
    recover(root, 2, swapped[0], swapped[1]);
  }

2.为了满足空间复杂度为O(1),使用Morris遍历算法
Morris遍历算法 具体内容查看Morris遍历算法

代码:

    public void recoverTree(TreeNode root) {
        //x存小索引那个结点,y存大索引那个结点,pre存前驱结点
        TreeNode x = null, y = null, pred = null;
        TreeNode node = root;
        while (node != null) {
            if (node.left == null) {
                if (pred != null && node.val < pred.val) {
                    if (x == null)
                        x = pred;
                    y = node;
                }
                pred = node;
                node = node.right;
            } else {
                TreeNode predecessor = node.left;
                while (predecessor.right != null && predecessor.right != node) {
                    predecessor = predecessor.right;
                }
                if (predecessor.right == null) {
                    predecessor.right = node;
                    node = node.left;
                } else {
                    if (pred != null && node.val < pred.val) {
                        if (x == null)
                            x = pred;
                        y = node;
                    }
                    pred = node;
                    predecessor.right = null;
                    node = node.right;
                }
            }
        }
        int t = x.val;
        x.val = y.val;
        y.val = t;
    }

以上是关于LeetCode——恢复二叉搜索树的主要内容,如果未能解决你的问题,请参考以下文章

⭐算法入门⭐《二叉树 - 二叉搜索树》中等09 —— LeetCode 99. 恢复二叉搜索树

leetcode-----99. 恢复二叉搜索树

LeetCode第九十九题—恢复二叉搜索树—Python实现

leetcode 每日一题 99. 恢复二叉搜索树

Leetcode 99.恢复二叉搜索树

[LeetCode] 99. 恢复二叉搜索树