1438. 绝对差不超过限制的最长连续子数组

一、 题目

在这里插入图片描述

二、 示例

在这里插入图片描述

三、 思路与代码

1. 思路:

  • 采用滑动窗口算法, 而关于窗口容器采用一个特殊的数据结构, 即multiset;
    • 在 C++ 中 multiset 内部元素是有序的,基于红黑树实现。multiset 可以有重复元素;
  • 本题的关键就在于, 如何快速的找到窗口内的最大值与最小值? 利用multiset, mutiset.rbegin()返回引用multiset容器最后一个元素(最大值)的反向迭代器, 而multiset.begin()则是正向迭代器;
    • 因为, 只要窗口中最大值与最小值之间的差值都超过了限制值limit, 则说明任意两个数字之间的差都不符合;
  • 首先,right指针移动滑动窗口;而当窗口中最大值与最小值之间的差超过了限制limit, 则left指针移动收缩窗口(multiset.erase());
  • 更新答案的时机为:窗口中最大值与最小值的差不超过limit时, 更新数据;
  • 注意从窗口中移出元素的操作!!!:这里用的是multiset容器(因为题目给出的值可能有重复), 所以在删除的时候不能直接erase, 这样会把所有重复的值都删除掉, 要先windows.find(value):multiset::find(是C++ STL中的内置函数,该函数返回指向在多集容器中搜索的元素的lower_bound的迭代器。如果未找到该元素,则迭代器指向该集合中最后一个元素之后的位置;找到后再erase掉, 这样从窗口中移出元素才是正确的;具体见代码解析;

2. 代码:

  • 代码中包含详细解析
class Solution {
public:
    int longestSubarray(vector<int>& nums, int limit) {

        // 使用 multiset
        multiset<int> mst;  // 内部原理是平衡二叉搜索树
        int left = 0;
        int right = 0;
        int n_len = nums.size();
        int cnt = 0;
        while (right < n_len) {
            int c = nums[right];
            right++;
            mst.insert(c);  // 使用multiset 的目的就是为了获得移入窗口中的数字的最大和最小值
            // 当差距超过limit时, 就不连续了即收缩窗口
            while (*mst.rbegin() - *mst.begin() > limit) {
                int d = nums[left];
                left++; // left 移动收缩窗口
                mst.erase(mst.find(d)); // 将该数字移出窗口

            }
            cnt = max(cnt, right - left);
        }
        return cnt;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值