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?
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
1 / \ 2 3 / 4 \ 5The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".题意:二叉搜索树中有两个元素是乱序的,请将他们转换成为真正的二叉搜索树;
思路:首先我们想到最直接的想法是中序遍历得到的中序序列,搜索二叉树中的中序遍历是非递减序列。那么问题就转化为在非递减有序列中交换两个数的位置,找出这两个数并恢复有序序列。
这个问题可以分为两步1.首先找到第一个错误的数first,即第一个比它后缀的数大的数;2.然后找到第一个错误位置应该在的位置,即第二个错误数的位置,也就是说找到第一个比first大数的前驱;
这个前驱就是第一个错误的数应该放的位置,也就是第二个错误的位置。
注意:这里有一个特殊情况,(0,1)first为1,没有找到比first大的数,这时second就是0[cpp] view plain copy
class Solution
{
public:
void recoverTree(TreeNode* root)
{
TreeNode* pre = NULL;
TreeNode* first = NULL;
TreeNode* second = NULL;
inorder(root, pre, first, second);
if (first!=NULL)
{
if (second==NULL)
{
second = pre;
}
int tmp = first->val;
first->val = second->val;
second->val = tmp;
}
}
void inorder(TreeNode* root, TreeNode* &pre,
TreeNode* &first, TreeNode* & second)
{
if (root==NULL)
{
return;
}
if (root->left)
{
inorder(root->left, pre, first, second);
}
if (pre!=NULL)
{
if (first==NULL && root->val<pre->val)
{
first = pre;
}
else if (first && root->val>=first->val)
{
second = pre;
return;
}
}
pre = root;
if (root->right)
{
inorder(root->right, pre, first, second);
}
}
};