zoukankan      html  css  js  c++  java
  • 子数组最大最小值之差——双指针+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中平衡树在算法题目的应用

    个性签名:时间会解决一切
  • 相关阅读:
    视频相关一些基础概念解析
    git
    mysql数据库查找类型不匹配
    matlab转python
    神经网络(二)
    python图片处理(三)
    python图片处理(二)
    python图片处理(一)
    python图片处理和matlab图片处理的区别
    MapReduce原理与设计思想
  • 原文地址:https://www.cnblogs.com/lfri/p/15770917.html
Copyright © 2011-2022 走看看