每日一题DAY14恢复二叉搜索树

本文介绍了一种在O(n)时间复杂度内恢复被错误修改节点的二叉搜索树的方法。利用中序遍历特性,找到两个逆序节点并进行交换,实现树的修复。通过优化,将空间复杂度降低至常数级别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

恢复二叉搜索树

难度:hard 本次用时:20min
关键词:树,中序遍历
在这里插入图片描述

二叉搜索树中序遍历下有序,O(n)的话是遍历然后交换一个逆序对
从左到右是升序,第一个违反的数;从右往左降序,第一个违反的数(从交换来看就很容易理解)
时空复杂度都是O(n)
如何优化到常数空间?左端数可以通过记录pre来获取,第一次pre>cur,记住这个pre, 获取右端,从右往左看,也就是cur < pre的数,记住更新到最后的值

class Solution {
    TreeNode* pre;
    TreeNode* cur;
    TreeNode* ext1;
    TreeNode* ext2;
    bool begins;
    bool findext1;
    void inOrder(TreeNode* root){
        if (root == nullptr)
            return;
        inOrder(root->left);
        if (begins){
            pre = root;
            begins = false;
        }
        cur = root;
        if (pre->val > cur->val && findext1 == false){
            ext1 = pre;
            findext1 = true;
        }
        if (cur->val < pre->val)
            ext2 = cur;
        pre = cur; //记得更新pre
        inOrder(root->right);

    }
public:
    void recoverTree(TreeNode* root) {
        //init
        begins = true;
        findext1 = false;
        pre = nullptr;
        cur = nullptr;
        ext1 = nullptr;
        ext2 = nullptr;
        //
        inOrder(root);
        //交换回去
        if (ext1 == nullptr || ext2 == nullptr)
            return;
        int temp = ext1->val;
        ext1->val = ext2->val;
        ext2->val = temp;
    }
};

优化一下代码,begins和findext1可以去除

class Solution {
    TreeNode* pre;
    TreeNode* cur;
    TreeNode* ext1;
    TreeNode* ext2;
    bool findext1;
    void inOrder(TreeNode* root){
        if (root == nullptr)
            return;
        inOrder(root->left);
        if (pre == nullptr){
            pre = root;
        }
        cur = root;
        if (pre->val > cur->val && ext1 == nullptr){
            ext1 = pre;
        }
        if (cur->val < pre->val)
            ext2 = cur;
        pre = cur; //记得更新pre
        inOrder(root->right);

    }
public:
    void recoverTree(TreeNode* root) {
        //init
        pre = nullptr;
        cur = nullptr;
        ext1 = nullptr;
        ext2 = nullptr;
        //
        inOrder(root);
        //交换回去
        if (ext1 == nullptr || ext2 == nullptr)
            return;
        int temp = ext1->val;
        ext1->val = ext2->val;
        ext2->val = temp;
    }
};

时间复杂度O(n).空间复杂度O(H) (递归栈深)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值