Leetcode | Recover Binary Search Tree
2014-05-15 21:50
323 查看
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
做到这里又有点不知道BST是什么。BST就是二叉树,并且左子树必定比root小,右子树必定比root大。这样中序遍历之后,一定就是一个递增的序列。所以BST和中序遍历经常挂在一起。
这道题是有两个数交换了。交换之后有可能,一是造成了交换了这个数一种可能造成了两个位置的变化,一是左子树比根大,一是右子树比根小。比如{2,3,1}这种情况,那么交换了2和1,造成了一开始3比2大,是错的,1比3小。另一种可能就是只造成一边出错。比如{4,1,2},4和2交换了,造成了root和右子树出错。
算法的思路如下,就是中序遍历的时候,记录了每个节点前一个节点。如果pre->val>root->val。这里因为pre不会再被访问到,如果pre之前为空,那么可以给pre赋值,否则下一次赋值很可能就是当前的root。root就一定会被记录下来。通过这种方式来保证找到的两个指针不一样。
因为使用了中序遍历,那么就需要用到栈,至少也要O(lgn)。如水中的鱼所讲,可以用Morris Traversal代中序遍历用O(1)的空间来做。Morris Traversal在Annie Kim这篇blog讲得很清楚。明天再自己写一遍。
Morris Traversal的思想就是:
1. 从左子树中找到最右的一个数,把它指向当前节点,以便下次访问的时候回溯回当前节点。
2. 如果这个最右节点已经指向当前节点,证明左子树已经访问完了,此时就可以开始访问右子树了。
因为第一次访问构建回溯链,第二次访问去掉回溯链。
Recover the tree without changing its structure.
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
做到这里又有点不知道BST是什么。BST就是二叉树,并且左子树必定比root小,右子树必定比root大。这样中序遍历之后,一定就是一个递增的序列。所以BST和中序遍历经常挂在一起。
这道题是有两个数交换了。交换之后有可能,一是造成了交换了这个数一种可能造成了两个位置的变化,一是左子树比根大,一是右子树比根小。比如{2,3,1}这种情况,那么交换了2和1,造成了一开始3比2大,是错的,1比3小。另一种可能就是只造成一边出错。比如{4,1,2},4和2交换了,造成了root和右子树出错。
算法的思路如下,就是中序遍历的时候,记录了每个节点前一个节点。如果pre->val>root->val。这里因为pre不会再被访问到,如果pre之前为空,那么可以给pre赋值,否则下一次赋值很可能就是当前的root。root就一定会被记录下来。通过这种方式来保证找到的两个指针不一样。
/** * Definition for binary tree * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void recoverTree(TreeNode *root) { n1 = n2 = pre = NULL; inorder(root); if (n1 && n2) swap(n1->val, n2->val); } void inorder(TreeNode *root) { if (!root) return; inorder(root->left); if (pre && pre->val > root->val) { if (!n1) n1 = pre; n2 = root; } pre = root; inorder(root->right); } private: TreeNode *n1; TreeNode *n2; TreeNode *pre; };
因为使用了中序遍历,那么就需要用到栈,至少也要O(lgn)。如水中的鱼所讲,可以用Morris Traversal代中序遍历用O(1)的空间来做。Morris Traversal在Annie Kim这篇blog讲得很清楚。明天再自己写一遍。
class Solution { public: void recoverTree(TreeNode *root) { n1 = n2 = pre = NULL; TreeNode* current = root; while (current != NULL) { if (current->left == NULL) { if (pre && pre->val > current->val) { if (!n1) n1 = pre; n2 = current; } pre = current; current = current->right; } else { TreeNode* rightmost = current->left; while (rightmost->right != NULL && rightmost->right != current) rightmost = rightmost->right; if (rightmost->right == NULL) { rightmost->right = current; current = current->left; } else { rightmost->right = NULL; if (pre && pre->val > current->val) { if (!n1) n1 = pre; n2 = current; } pre = current; current = current->right; } } } if (n1 && n2) swap(n1->val, n2->val); } private: TreeNode *n1; TreeNode *n2; TreeNode *pre; };
Morris Traversal的思想就是:
1. 从左子树中找到最右的一个数,把它指向当前节点,以便下次访问的时候回溯回当前节点。
2. 如果这个最右节点已经指向当前节点,证明左子树已经访问完了,此时就可以开始访问右子树了。
因为第一次访问构建回溯链,第二次访问去掉回溯链。
相关文章推荐
- [Leetcode] Recover Binary Search Tree
- leetcode -- Recover Binary Search Tree
- LeetCode OJ:Recover Binary Search Tree(恢复二叉搜索树)
- [LeetCode]Recover Binary Search Tree
- leetcode 099 —— Recover Binary Search Tree
- [LeetCode] 078: Recover Binary Search Tree
- 【leetcode】Recover Binary Search Tree
- LeetCode 99: Recover Binary Search Tree
- [leetcode]Recover Binary Search Tree
- LeetCode 99 Recover Binary Search Tree(Python详解及实现)
- LeetCode | Recover Binary Search Tree
- [Leetcode] Recover Binary Search Tree (Java)
- LeetCode -- Recover Binary Search Tree
- 【LeetCode】 Recover Binary Search Tree BST 中序遍历
- 【LeetCode】Recover BinarySearch Tree
- Leetcode: Recover Binary Search Tree
- leetcode Recover Binary Search Tree
- leetcode Recover Binary Search Tree
- LeetCode – Refresh – Recover Binary Search Tree
- leetcode--RecoverBinarySearchTree