Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure. (Hard)
Note:
A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?
分析:
BST的中序遍历应该是递增的,我们考虑这样一个中序遍历序列1,2,6,4,5,3,7,其中3,6是交换了位置的。
所以我们就按照中序遍历的顺序遍历树,记录cur, prev, beforePrev三个变量;
第一次出现before < prev > cur的prev即为要交换的第一个元素,最后一个满足beforePrev > prev < cur的即为要交换的另一个元素。
然后再遍历一遍把这两个节点找出来,交换其value值即可。
注意:比如1,0这种样例,当最后一个节点是被交换的元素的时候,无法用上述判断,但如果其满足prev > cur说明cur即为要交换的元素。
代码:
1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 int beforePrev = -0x7FFFFFFF, prev = -0x7FFFFFFF, cur = -0x7FFFFFFF; 12 int s1 = -0x7FFFFFFF, s2 = -0x7FFFFFFF; 13 TreeNode* t1; 14 TreeNode* t2; 15 private: 16 void helper(TreeNode* root) { 17 if (root == nullptr) { 18 return; 19 } 20 helper(root -> left); 21 beforePrev = prev; 22 prev = cur; 23 cur = root -> val; 24 if (beforePrev < prev && prev > cur && s1 == -0x7FFFFFFF) { 25 s1 = prev; 26 } 27 if (beforePrev > prev && prev < cur ) { 28 s2 = prev; 29 } 30 31 helper(root -> right); 32 } 33 34 void dfs(TreeNode* root) { 35 if (root == nullptr) { 36 return; 37 } 38 dfs(root -> left); 39 if (root -> val == s1) { 40 t1 = root; 41 } 42 if (root -> val == s2) { 43 t2 = root; 44 } 45 dfs(root -> right); 46 } 47 public: 48 void recoverTree(TreeNode* root) { 49 helper(root); 50 if (cur < prev) { 51 s2 = cur; 52 } 53 dfs(root); 54 swap(t1 -> val, t2 -> val); 55 return; 56 } 57 };