[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); } };