题目如下:
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?
分析如下:
第一个做法,也是我目前想到的最好的做法,是O(n) 空间复杂度的做法。就是在中序遍历的基础上,每两个元素为一组,检查是否是顺序颠倒的。
case1 : 发生顺序颠倒的两个元素是相邻元素
case2 : 发生顺序颠倒的两个元素不是相邻元素
代码如下:
//400ms通过大集合,我很好奇,这时间居然没有超时么?
/**
* 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) {
if(root==NULL)
return;
stack<TreeNode*> node_stack;
while(root!=NULL){
node_stack.push(root);
root=root->left;
}
TreeNode* cur=NULL;
TreeNode* pre=NULL;
TreeNode* res_a=NULL;
TreeNode* res_b=NULL;
while(!node_stack.empty()) {
cur=node_stack.top();
node_stack.pop();
if(pre!=NULL&&cur->val<=pre->val&&res_a==NULL){
res_a=pre;
res_b=cur;
}else if(pre!=NULL&&cur->val<=pre->val&&res_a!=NULL) {
res_b=cur;
}
pre=cur;
cur=cur->right;
while(cur!=NULL){
node_stack.push(cur);
cur=cur->left;
}
}
int tmp=res_a->val;
res_a->val=res_b->val;
res_b->val=tmp;
return;
}
};
第二个做法,相当聪明。做到了O(1)的空间复杂度。
分析一下,要找到顺序颠倒的点,必然要中序遍历,如果中序遍历,要么用栈,要么非递归。如果用栈,必然用O(N)的空间复杂度。如果非递归,至少还有改造的希望。
于是问题转化为,改造递归的中序遍历,使得它的空间复杂度为O(1)并且依然能够找到顺序颠倒的点。
代码如下,搬运自 Yu's Coding Garden
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *first;
TreeNode *second;
TreeNode *pre;
void inOrder(TreeNode *root){
if (root==NULL)
return;
inOrder(root->left);
if (pre == NULL){pre = root;}
else {
if (pre->val > root->val){
if (first==NULL) {first = pre;}
second = root;
}
pre = root;
}
inOrder(root->right);
}
void recoverTree(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
pre = NULL;
first = NULL;
second= NULL;
inOrder(root);
int val;
val = first->val;
first->val=second->val;
second->val=val;
return;
}
};