Description:
Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Solution:
这道题如果不考虑空间占用的话只要中序遍历找到乱序的两个数就可以了。但是题目中有说最好使用一个空间为O(1)的算法。那我们需要中序遍历整棵数,并记录和维护当前节点及当前节点中序遍历的前一个节点。不使用递归可以使用Morris遍历来实现。即,若当前节点存在左子树,使用循环来寻找当前节点的上一个节点,并把上一个节点的右节点链接到当前节点,然后当前节点左移;若当前节点不存在左子树,则当前节点右移。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void recoverTree(TreeNode* root) {
TreeNode *first = NULL, *second = NULL;
TreeNode* cur = root; TreeNode* prior = NULL, *tmp = NULL;
while(cur) {
if (cur->left) {
tmp = cur->left;
while(tmp->right && tmp->right != cur) tmp = tmp->right;
if (tmp->right == cur) {
tmp->right = NULL;
prior = tmp;
if (prior != NULL && prior->val > cur->val) { if (first == NULL) first = prior; second = cur; }
prior = cur;
cur = cur->right;
}
else {
tmp->right = cur;
cur = cur->left;
}
}
else {
if (prior != NULL && prior->val > cur->val) { if (first == NULL) first = prior; second = cur; }
prior = cur;
cur = cur->right;
}
}
if (first != NULL && second != NULL) {
int temp = first->val;
first->val = second->val;
second->val = temp;
}
}
};