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?
思路:
对二叉搜索树进行中序遍历,可以得到排序好的数组。如果二叉树中,两个节点被swap,那么第一个节点的中序后继必然小于它,第二个节点必然小于它的中序前继。因此,对二叉树进行中序遍历,即可得到两个出错节点的指针。对二叉树中序遍历,可以采用递归方式,也可以采用迭代方式。我分别用这两种方式实现。但是无论使用迭代方式,还是递归方式,算法空间复杂度均为O(logn)。而题目要求空间复杂度为常数让人很迷惑。因为就算是使用递归方式遍历,其调用栈的空间复杂度也在O(logn)。
代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
TreeNode* prev, *mistake1, *mistake2;
void inOrder(TreeNode* root)
{
if(root == NULL)
return;
inOrder(root->left);
if(prev != NULL && prev->val > root->val)
{
if(mistake1 == NULL)
{
mistake1 = prev;
mistake2 = root;
}
else
mistake2 = root;
}
prev = root;
inOrder(root->right);
}
void inOrderIter(TreeNode* root)
{
if(root == NULL)
return;
stack<TreeNode *> s;
TreeNode* p = root;
while(!s.empty() || p)
{
if(p)
{
s.push(p);
p = p->left;
}
else
{
p = s.top();
if(prev != NULL && prev->val > p->val)
{
if(mistake1 == NULL)
{
mistake1 = prev;
mistake2 = p;
}
else
mistake2 = p;
}
prev = p;
s.pop();
p = p->right;
}
}
}
public:
void recoverTree(TreeNode *root) {
prev = mistake1 = mistake2 = NULL;
//inOrder(root);
inOrderIter(root);
if(mistake1 != NULL && mistake2 != NULL)
{
int temp = mistake1->val;
mistake1->val = mistake2->val;
mistake2->val = temp;
}
}
};