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?
如果使用额外空间,即中序遍历,然后将中序便利结果排序(也可以不排序,直接找,从左到右找最左侧不符合顺序的为n1,从右到左找不符合顺序的为n2),最后将排序好的结果再填进去
class Solution {
public:
void recoverTree(TreeNode* root) {
//Inorder
vector<int> v;
TreeNode *pCur = root;
stack<TreeNode*> s;
while (!s.empty() || pCur) {
while (pCur) {
s.push(pCur);
pCur = pCur->left;
}
if(!s.empty()){
v.push_back(s.top()->val);
pCur = s.top()->right;
s.pop();
}
}
sort(v.begin(),v.end());
int idx = 0;
pCur = root;
stack<TreeNode*> s1;
while (!s1.empty() || pCur) {
while (pCur) {
s1.push(pCur);
pCur = pCur->left;
}
if(!s1.empty()){
s1.top()->val = v[idx++];
pCur = s1.top()->right;
s1.pop();
}
}
}
};
其实如果写完上面程序,其实可以发现,没必要使用vector额外空间,中序遍历过程中就可以找到n1和n2
class Solution {
public:
void recoverTree(TreeNode* root) {
TreeNode *pCur = root;
stack<TreeNode*> s;
TreeNode *pre1 = NULL;
TreeNode *leftToSwap = NULL;
TreeNode *rightToSwap = NULL;
int cntUnorder = 0;
while (!s.empty() || pCur) {
while (pCur) {
s.push(pCur);
pCur = pCur->left;
}
if(!s.empty()){
//search from left to find the non-order node
if(!pre1)
pre1 = s.top();
else{
if(s.top()->val < pre1->val){
cntUnorder ++;
if(!leftToSwap) leftToSwap = pre1;
rightToSwap = s.top();
if(cntUnorder>=2)
break;
}
pre1 = s.top();
}
//
pCur = s.top()->right;
s.pop();
}
}
int temp = leftToSwap->val;
leftToSwap->val = rightToSwap->val;
rightToSwap->val = temp;
}
};
即便如此,还是使用了O(n)的额外空间,中序遍历如何不使用额外空间呢,那只能递归了,同时一些关键变量就需要作为成员变量而不是局部变量
class Solution {
public:
TreeNode *pre1;
TreeNode *leftToSwap;
TreeNode *rightToSwap;
void recoverTree(TreeNode* root) {
pre1 = leftToSwap = rightToSwap = NULL;
inOrder(root);
int temp = leftToSwap->val;
leftToSwap->val = rightToSwap->val;
rightToSwap->val = temp;
}
void inOrder(TreeNode *root)
{
if(root == NULL) return;
inOrder(root->left);
if(!pre1)
pre1 = root;
else{
if(root->val < pre1->val){
if(!leftToSwap) leftToSwap = pre1;
rightToSwap = root;
}
pre1 = root;
}
inOrder(root->right);
}
};