NO.99 恢复二叉搜索树

二叉搜索树中的两个节点被错误地交换。

请在不改变其结构的情况下,恢复这棵树。

示例 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% 的用户

猜你喜欢

转载自blog.csdn.net/xuyuanwang19931014/article/details/91384510