LeetCode99—Recover Binary Search Tree

LeetCode99—Recover Binary Search Tree

恢复排序二叉树


原题

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.

Subscribe to see which companies asked this question

排序二叉树当中出现了两个元素的交换,这导致排序二叉树的性质不再,请恢复他原来的样子,且不能改变其结构。


分析

主要是不能改变结构这点让人头疼,一直没有找到合适的办法,看了网上的思路:
由于排序二叉树的中序遍历是递增序列,假如是1234567 ,那么假设当相邻两个访问的节点发生交换,比如23交换,则中序遍历序列变成了,1324567,此时序列中有1一个逆序对,我们直接交换这个逆序对即可。假设不是相邻的两个节点发生交换,即假设26交换,则中序遍历序列变成了1634527,出现了63和52两个逆序对,这个时候我们要将第一个逆序对的第一个元素和第二个逆序对的第二个元素交换。基于上述说明,这题可以这样,首先中序遍历,维护一个变量记录前一个访问的节点值,当出现第一次逆序时,我们把前一个访问节点和当前节点全部放入vector中,遍历结束我们对vector进行判断,有如下几种情况:
1. 为空,没有逆序对,不做任何操作
2. 不为空,判断容器大小:
  a.vec.size()==2,直接交换两值即可。
  b.vec.size()==4,交换vec[0]和vec[3]第一个逆序的第一个数和第二个逆序的第二个数。
  c.这是写代码的时候发生的一个意外没有考虑,也就是当被交换的数隔一个节点时:例如当原本的访问顺序为1234567,3和5交换则出现访问序列1254367,这里确实有两个逆序对,54和43,但是他们公用了一个元素4,所以在最后判断的时候加上vec.size()==3这个条件。


代码

class Solution {
private:
    void helper(TreeNode*root, TreeNode*&pre, vector<TreeNode*>&res)
    {
        if (root == NULL)
            return;
        helper(root->left, pre, res);
        if (pre != NULL&&pre->val > root->val)
        {
            res.push_back(pre);
            res.push_back(root);
        }
        pre = root;
        helper(root->right, pre, res);
    }

public:
    void recoverTree(TreeNode* root) {
        vector<TreeNode*>res;
        TreeNode*pre = NULL;
        helper(root, pre, res);
        if (res.size() > 0)
        {
            if(res.size()==2)
                swap(res[0]->val, res[1]->val);
            if(res.size()==3)
                swap(res[0]->val,res[2]->val);
            if(res.size()==4)
                swap(res[0]->val,res[3]->val);
        }
    }
};

参考

http://blog.csdn.net/linhuanmars/article/details/24566995

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值