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;
}
};