LC918-环形子数组的最大和

918. 环形子数组的最大和

题意为求环状数组最大子序列和,长度不超过限制n。

对于非环状数组情况我们很容易解决,那么处理环状情况一般只需要将数组copy一份,“破环成链”。

对处理后的数组求其前缀和数组s,题意转为求:

\[对\space \space \forall i,\space j \space 求 \space \max\{s[i] - s[j]\ | i - n \leqslant j < i\} \]

枚举每一个i,则求在i确定的情况下,满足条件的s[j]的最小值,即求大小为n的滑动窗口的最小值,可利用单调队列解决。

即:将数组copy一份求前缀和+单调队列

const int N = 6e4 + 10;
int q[N],hh,tt = -1;
class Solution {
public:
    int maxSubarraySumCircular(vector<int>& nums) {
        hh = 0, tt = -1;
        int n = nums.size();
        vector<int>s(2 * n + 1);
        for(int i = 1; i < s.size(); ++i){
            s[i] = s[i - 1] + nums[(i - 1) % n];
        }
        int ans = INT_MIN;
        q[++tt] = 0;
        for(int i = 1; i < s.size(); ++i){
            while(hh <= tt && i - n > q[hh]) hh++;
            ans = max(ans, s[i] - s[q[hh]]);
            while(hh <= tt && s[q[tt]] >= s[i]) tt--;
            q[++tt] = i; 
        }
        return ans;
    }
};
posted @ 2021-08-06 21:20  Ivessas  阅读(108)  评论(0)    收藏  举报