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,找到不符合val递增的两个点。前面分析过中序遍历的三种方法,这里题目要求用O(1)的空间,所以不采用递归和栈的方式。那么通过下面的代码中需遍历BST。
void InoderTraversal(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
TreeNode* cur = root;
TreeNode* prev = NULL;
while(cur != NULL)
{
if(cur->left != NULL)
{
prev = cur->left;
while(prev->right != NULL && prev->right != cur) prev = prev->right;
if(prev->right == cur){
//TODO:
prev->right = NULL;
cur = cur->right;
}else{
prev->right = cur;
cur = cur->left;
}
}else{
//TODO:
cur = cur->right;
}
}
}
在TODO处完成了当前节点的遍历,开始右子树,所以在这里比较val确定错位。
为了定位错位的两个Node,需要一个记录中序遍历的前一个节点的指针preVisited。完整代码如下:
/**
* 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) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
TreeNode* e1 = NULL;
TreeNode* e2 = NULL;
TreeNode* cur = root;
TreeNode* prev = NULL;
TreeNode* preVisited = NULL;
while(cur != NULL)
{
if(cur->left != NULL)
{
prev = cur->left;
while(prev->right != NULL && prev->right != cur) prev = prev->right;
if(prev->right == cur){
//TODO:
if(preVisited != NULL && preVisited->val > cur->val){
if(e1 == NULL){
e1 = preVisited;
}
e2 = cur;
}
prev->right = NULL;
preVisited = cur;
cur = cur->right;
}else{
prev->right = cur;
cur = cur->left;
}
}else{
//TODO:
if(preVisited != NULL && preVisited->val > cur->val){
if(e1 == NULL){
e1 = preVisited;
}
e2 = cur;
}
preVisited = cur;
cur = cur->right;
}
}
if(e1 != NULL && e2 != NULL) swap(e1->val,e2->val);
}
};
296 milli secs.