wo 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?
题目解析:
做题要看问题的对象。这个题目是二叉搜索树的两个结点交换了,带来的结果是,中序遍历得到的不是有序的。很简单的方法是,设置一个n的数组,然后中序遍历,最后交换两个不符合规则的结点。
题目中要求使用常量空间,那么我们从上面的中序遍历中怎么得到启发呢?先看中序遍历后如何找到两个不符合规则的结点。比如:1-2-7-4-5-6-3-8。显然3要和7进行交换。那么怎么找到7,怎么找到3?从前向后遍历,当当前值比前一个值小的时候,前一个值要和后面的交换,再往后遍历,当当前值比前一个数小的时候,说明找到了第二个结点。然后将找到的两个结点交换。
有两个需要注意的地方:
1、两次查找的时候,都是当前值比前一个小的时候,但第一次取前一个值,第二个取后一个值。
2、如果需要交换的两个点正好相邻呢?所有当big被赋值的时候,small也要被赋值!
class Solution {
public:
void recoverTree(TreeNode *root) {
if(root == NULL)
return ;
InOrderTraverse(root);
}
void InOrderTraverse(TreeNode *root){
stack<TreeNode *> S;
TreeNode *p = root;
vector<int> num;
TreeNode *tmp = NULL;
TreeNode *big = NULL;
TreeNode *small = NULL;
bool flag = false;
while(p || !S.empty()){
if(p){
S.push(p);
p = p->left;
}else{
p = S.top();
S.pop();
if(tmp == NULL){
tmp = p;
p = p->right;
continue;
}
if(!flag){
if(tmp->val > p->val){
big = tmp;
small = p;
flag = true;
}
}else{
if(tmp->val > p->val){
small = p;
break;
}
}
tmp = p;
p = p->right;
}
}
int a = big->val;
big->val = small->val;
small->val = a;
}
};