Two elements of a binary search tree (BST) are swapped by mistake.
Recover the tree without changing its structure.
Note:
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?
二叉搜索树中有两个节点位置互换,要求恢复原始二叉树(找出这两个节点并交换值)
直观的办法就是进行中序遍历,然后找出没有按照升序排列的两个点的值并交换。通常中序遍历可以通过递归或者使用栈进行迭代来完成。但题目要求constant space,所以这里可以使用Morris Traversal,空间复杂度为O(1).
Morris Traversal方法:点击打开链接
这道题对Morris Traversal稍加修改即可,需要添加一个prevVisited指针指向上一个中序遍历访问过的点,并比较它和当前指针curr的值。
/**
* 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)
{
TreeNode *curr = root, *prev = NULL, *prevVisited = NULL;
TreeNode *f1 = NULL, *f2 = NULL;
while (curr)
{
if (curr->left == NULL)
{
if (prevVisited != NULL && prevVisited->val > curr->val)
{
if (!f1)
{
f1 = prevVisited;
}
f2 = curr;
}
prevVisited = curr;
curr = curr->right;
}
else
{
prev = curr->left;
while (prev->right != NULL && prev->right != curr)
{
prev = prev->right;
}
if (prev->right == NULL)
{
prev->right = curr;
curr = curr->left;
}
else
{
prev->right = NULL;
if (prevVisited != NULL && prevVisited->val > curr->val)
{
if (!f1)
{
f1 = prevVisited;
}
f2 = curr;
}
prevVisited = curr;
curr = curr->right;
}
}
}
int tmp = f1->val;
f1->val = f2->val;
f2->val = tmp;
return;
}
};