zoukankan      html  css  js  c++  java
  • [LeetCode] 99. Recover Binary Search Tree 复原二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake.

    Recover the tree without changing its structure.

    Example 1:

    Input: [1,3,null,null,2]
    
       1
      /
     3
      
       2
    
    Output: [3,1,null,null,2]
    
       3
      /
     1
      
       2
    

    Example 2:

    Input: [3,1,4,null,null,2]
    
      3
     / 
    1   4
       /
      2
    
    Output: [2,1,4,null,null,3]
    
      2
     / 
    1   4
       /
      3
    

    Follow up:

    • A solution using O(n) space is pretty straight forward.
    • Could you devise a constant space solution?

    二叉搜索树的2个元素被错误的交换了,在不改变结构的情况下恢复二叉搜索树。follow up: 用常量空间。

    Java:

    public class Solution {
        
        TreeNode firstElement = null;
        TreeNode secondElement = null;
        // The reason for this initialization is to avoid null pointer exception in the first comparison when prevElement has not been initialized
        TreeNode prevElement = new TreeNode(Integer.MIN_VALUE);
        
        public void recoverTree(TreeNode root) {
            
            // In order traversal to find the two elements
            traverse(root);
            
            // Swap the values of the two nodes
            int temp = firstElement.val;
            firstElement.val = secondElement.val;
            secondElement.val = temp;
        }
        
        private void traverse(TreeNode root) {
            
            if (root == null)
                return;
                
            traverse(root.left);
            
            // Start of "do some business", 
            // If first element has not been found, assign it to prevElement (refer to 6 in the example above)
            if (firstElement == null && prevElement.val >= root.val) {
                firstElement = prevElement;
            }
        
            // If first element is found, assign the second element to the root (refer to 2 in the example above)
            if (firstElement != null && prevElement.val >= root.val) {
                secondElement = root;
            }        
            prevElement = root;
    
            // End of "do some business"
    
            traverse(root.right);
    }
    

    Python:  

    # Time:  O(n)
    # Space: O(1)
    class TreeNode(object):
        def __init__(self, x):
            self.val = x
            self.left = None
            self.right = None
    
        def __repr__(self):
            if self:
                serial = []
                queue = [self]
    
                while queue:
                    cur = queue[0]
    
                    if cur:
                        serial.append(cur.val)
                        queue.append(cur.left)
                        queue.append(cur.right)
                    else:
                        serial.append("#")
    
                    queue = queue[1:]
    
                while serial[-1] == "#":
                    serial.pop()
    
                return repr(serial)
    
            else:
                return None
    

    Python:

    class Solution(object):
        # @param root, a tree node
        # @return a tree node
        def recoverTree(self, root):
            return self.MorrisTraversal(root)
    
        def MorrisTraversal(self, root):
            if root is None:
                return
            broken = [None, None]
            pre, cur = None, root
    
            while cur:
                if cur.left is None:
                    self.detectBroken(broken, pre, cur)
                    pre = cur
                    cur = cur.right
                else:
                    node = cur.left
                    while node.right and node.right != cur:
                        node = node.right
    
                    if node.right is None:
                        node.right =cur
                        cur = cur.left
                    else:
                        self.detectBroken(broken, pre, cur)
                        node.right = None
                        pre = cur
                        cur = cur.right
    
            broken[0].val, broken[1].val = broken[1].val, broken[0].val
    
            return root
    
        def detectBroken(self, broken, pre, cur):
            if pre and pre.val > cur.val:
                if broken[0] is None:
                    broken[0] = pre
                broken[1] = cur

    C++:

    // O(n) space complexity
    class Solution {
    public:
        void recoverTree(TreeNode *root) {
            vector<TreeNode*> list;
            vector<int> vals;
            inorder(root, list, vals);
            sort(vals.begin(), vals.end());
            for (int i = 0; i < list.size(); ++i) {
                list[i]->val = vals[i];
            }
        }
        void inorder(TreeNode *root, vector<TreeNode*> &list, vector<int> &vals) {
            if (!root) return;
            inorder(root->left, list, vals);
            list.push_back(root);
            vals.push_back(root->val);
            inorder(root->right, list, vals);
        }
    };
    

    C++:

    // Still O(n) space complexity
    class Solution {
    public:
        TreeNode *pre;
        TreeNode *first;
        TreeNode *second;
        void recoverTree(TreeNode *root) {
            pre = NULL;
            first = NULL;
            second = NULL;
            inorder(root);
            if (first && second) swap(first->val, second->val);
        }
        void inorder(TreeNode *root) {
            if (!root) return;
            inorder(root->left);
            if (!pre) pre = root;
            else {
                if (pre->val > root->val) {
                    if (!first) first = pre;
                    second = root;
                }
                pre = root;
            }
            inorder(root->right);
        }
    };
    

    C++:

    // O(1) space complexity
    class Solution {
    public:
        void recoverTree(TreeNode *root) {
            TreeNode *first = NULL, *second = NULL, *parent = NULL;
            TreeNode *cur, *pre;
            cur = root;
            while (cur) {
                if (!cur->left) {
                    if (parent && parent->val > cur->val) {
                        if (!first) first = parent;
                        second = cur;
                    }
                    parent = cur;
                    cur = cur->right;
                } else {
                    pre = cur->left;
                    while (pre->right && pre->right != cur) pre = pre->right;
                    if (!pre->right) {
                        pre->right = cur;
                        cur = cur->left;
                    } else {
                        pre->right = NULL;
                        if (parent->val > cur->val) {
                            if (!first) first = parent;
                            second = cur;
                        }
                        parent = cur;
                        cur = cur->right;
                    }
                }
            }
            if (first && second) swap(first->val, second->val);
        }
    };
    

      

      

      

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    HTML标签和属性三
    HTML标签和属性二
    HTML标签和属性一
    小程序相关面试题
    Vue路由的hash模式与history模式的区别?
    android中VideoView播放sd卡上面的视频
    Android中app开机自启动的开发
    java中byte,byte[]和int之间的转换
    Android多activity启动两种方式浅谈
    Android开发用到的几种常用设计模式浅谈(一):组合模式
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9795766.html
Copyright © 2011-2022 走看看