二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入: [1,3,null,null,2]
1
/
3
\
2
输出: [3,1,null,null,2]
3
/
1
\
2
示例 2:
输入: [3,1,4,null,null,2]
3
/ \
1 4
/
2
输出: [2,1,4,null,null,3]
2
/ \
1 4
/
3
进阶:
使用 O(n) 空间复杂度的解法很容易实现。
你能想出一个只使用常数空间的解决方案吗?
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
void recoverTree(struct TreeNode* root){
if(!root)return;
struct TreeNode * swap1=NULL;
struct TreeNode * swap2=NULL;
struct TreeNode * save=NULL;
struct TreeNode * pre=root;
struct TreeNode * cur=NULL;
while(pre)
{//查询pre节点的前序节点,若左节点为空,当前元素为即时最小元素
cur=pre->left;
if(cur)
{//左节点不为空
//第一次向右查找,会将pre节点用前序节点的右节点(前序节点的右节点为null)保存pre节点
//第二次向右查找,会将pre节点的存储删除
while(cur->right!=NULL&&cur->right!=pre)
{
cur=cur->right;
}
if(!cur->right)
{//第一次向右查找
//保存pre节点,保存位置为pre左子树的最后一个位置
cur->right=pre;
//更新pre节点,前移
pre=pre->left;
//继续查找前序节点
continue;
}
else
{//删除pre节点存储,恢复二叉树,第二次以当前pre节点作为pre节点时会进入此处,此时也会输出当前节点的值
cur->right=NULL;
}
}
//输出,记录异常节点位置
if(!save)save=pre;
else
{
if(pre->val<save->val)
{
if(swap1==NULL)
{
swap1=pre;
swap2=save;
}
else
{
swap1=pre->val<swap1->val?pre:swap1;
swap2=pre->val>swap2->val?pre:swap2;
}
}
save=pre;
}
//左子树及当前节点已比较完毕,更新当前节点为右子树起点
pre=pre->right;
}
if(swap1)
{
int tmp=swap1->val;
swap1->val=swap2->val;
swap2->val=tmp;
}
}
执行用时 : 20 ms, 在Recover Binary Search Tree的C提交中击败了100.00% 的用户
内存消耗 : 11.4 MB, 在Recover Binary Search Tree的C提交中击败了100.00% 的用户