二叉搜索树习题

力扣 99 题 : 力扣

思考二叉搜索树存在中序遍历为升序序列。

如下图: 中序遍历先左结点->根结点->右结点,结合上篇博文

二叉树的遍历_V0218的博客-CSDN博客

遍历结果应该为 1,2,3。

 利用中序遍历的特点,解题思路

       1. 中序遍历获取升序列表

        2. 找出升序列表中nums[i] > nums[i+1]的位置及值

        3. 交换错误数据位置的值。

代码实现

     

class Solution {
public:
    int x;
    int y;
    // 标记第一次X的位置
    bool firstF = true;
    void midOrder(vector<int>& nums, TreeNode* root)
    {
        if (root == nullptr) {
            return;
        }
        midOrder(nums, root->left);
        nums.push_back(root->val);
        midOrder(nums, root->right);
    }

    void FindLessPos(vector<int> &nums)
    {
        for (int i = 0; i < nums.size() - 1; ++i) {
            if (nums[i] > nums[i+1]) {
                y = nums[i+1];
                if (firstF) {
                    // 因为可能出现两个错误位置在不同的点
                    // 比如
                    // 第一种乱序 : 1,3,2,4,5   x = 3, y = 2
                    // 第二种乱序:  1,5,3,4,2   x = 5; y = 2
                    x = nums[i];
                    firstF = false;
                }
            }
        }
    }

    void Recover(TreeNode* root)
    {
        if (root == nullptr) {
            return;
        }
        if (root -> val == x) {
            root -> val = y;
        }else if (root -> val == y) {
            root -> val = x;
        }
        Recover(root->left);
        Recover(root->right);
    }

    void recoverTree(TreeNode* root) {
        //利用中序遍历
        vector<int> nums;
        midOrder(nums, root);
        //找到对应的递减的位置;
        FindLessPos(nums);
        //交换错误的位置
        Recover(root);
    }
};

 该种时间复杂度和空间复杂度都为 O(n);

进阶1

思考,我们可以在中序遍历的过程中就记录下对应的出现差错的位置,利用一个辅助指针pre 记录下前一个结点,根据中序遍历的结果(升序),前面一个结点的值一定小于后面结点的值,所以当发现前一个结点值比当前结点大时,该结点就是又问题的结点,记录下该结点的位置。

代码实现

class Solution {
public:
    TreeNode* x1 = nullptr;
    TreeNode* y1 = nullptr;
    TreeNode* pre = nullptr;
    void recoverTree2(TreeNode* root)
    {
        if (root == nullptr) {
            return;
        }
        recoverTree2(root->left);
        if (pre != nullptr && root->val < pre->val) {
            y1 = root;
            if (x1 == nullptr) {
                x1 = pre;
            }
        }
        pre = root;
        recoverTree2(root->right);
    }

    void recoverTree(TreeNode* root) {
        recoverTree2(root);
        int tmp = x1->val;
        x1->val = y1->val;
        y1->val = tmp;
    }
};

 该种方式时间复杂度O(n) 空间复杂度O(h).

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值