zoukankan      html  css  js  c++  java
  • 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;
        }
    
  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/xym4869/p/12936007.html
Copyright © 2011-2022 走看看