子数组最大最小值之差——双指针+multiset

维护满足某种条件的子数组,如果具有某种单调性,通常可以用双指针。

题目一

题目:题意:求最长的子串,且其最大值与最小值之差在[𝑚1,𝑚2]内,如果有多个,输出子串和最大的(华为机试题)
方法:
假设,我们已经有一组数字,我们继续添加数字时:当前这组数字的max-min要么增大,要么不变。而删除数字时,要么变小,要么不变(想想为什么)。可以用双指针来完成这个搜索的操作。
算法具体实现时,我们只要让l从1循环到n,r不断的向右跑以满足要求就可以了。求一堆数的最小最大值,并可以进行插入删除操作。这一部分用任意一种二叉搜索树就可以完成,比如红黑树。

typedef long long ll;
int longestSubarray(vector<int>& nums, int m1, int m2) {
    multiset<int>ms;
    int i = 0, j = 0, n = nums.size();
    vector<ll>sum(n+1, 0);
    for(int i = 1;i <= n;i++) {
        sum[i] = sum[i-1] + nums[i-1];
    }

    ll len = 0, max_sum = 0;

    while(j <= n) {
        int cha = ms.empty() ? 0 : *(--ms.end()) - *ms.begin();
        cout << i << " " << j << endl;
        cout << "cha: " << cha << endl;
        if(cha >= m1 && cha <= m2) {  // 可行区间,更新答案
            if(j-i >= len) {
                len = j-i;
                max_sum = max(max_sum, sum[j]-sum[i]);
            }
        } 
        if(j == n)  break;

        if(cha <= m2) {
            ms.insert(nums[j]);
            j++;
        } else {
            ms.erase(ms.find(nums[i]));
            i++;
        }
        

    }

    cout << "len: " << len << endl;
    cout << "max_sum: " << max_sum << endl;

    return len;
}

题目二

题目:LC1438. 绝对差不超过限制的最长连续子数组
方法:
一模一样,相当于上面的特例吧,m1=-limit, m2=limit

class Solution {
public:

    int mylongestSubarray(vector<int>& nums, int m1, int m2) {
        multiset<int>ms;
        int i = 0, j = 0, n = nums.size();
        int res = 0;

        while(j <= n) {
            int cha = ms.empty() ? 0 : *(--ms.end()) - *ms.begin();
            if(cha >= m1 && cha <= m2) {  // 可行区间,更新答案
                res = max(res, j-i);
            } 
            if(j >= n)  break;  // 最后一次j可能等于n

            if(cha <= m2) {
                ms.insert(nums[j]);
                j++;
            } else {
                ms.erase(ms.find(nums[i]));
                i++;
            }
        }
        return res;
    }

    int longestSubarray(vector<int>& nums, int limit) {
        return mylongestSubarray(nums, -limit, limit);
    }
};

参考链接:C++ STL中平衡树在算法题目的应用

posted @ 2022-01-06 14:23  Rogn  阅读(288)  评论(0编辑  收藏  举报