918. 环形子数组的最大和
对于环形数组,分两种情况。
(1)答案在数组中间,就是最大子序和。例如[1,-2,3,-2];
(2)答案在数组两边,例如[5,-3,5]最大的子序和就等于数组的总和SUM-最小的子序和。(一种特殊情况是数组全为负数,也就是SUM-最小子序和==0,最大子序和等于数组中最大的那个)。
class Solution {
public:
int maxSubarraySumCircular(vector<int>& nums) {
int sum=nums[0];
vector<int>dpmax(nums);
vector<int>dpmin(nums);
for(int i=1;i<nums.size();i++){
dpmax[i]=max(dpmax[i-1]+nums[i],nums[i]);
dpmin[i]=min(dpmin[i-1]+nums[i],nums[i]);
sum+=nums[i];
}
int maxv=*max_element(dpmax.begin(),dpmax.end());
int minv=*min_element(dpmin.begin(),dpmin.end());
return max(maxv,sum-minv==0?maxv:sum-minv);
}
};
1438. 绝对差不超过限制的最长连续子数组
使用滑动窗口保持符合条件的子数组,记录最长的长度
然后知道数组最大值和最小值
需要对滑入窗口的数据记录,滑出的数据删除,并且使这些记录方便的算出最大值和最小值
int longestSubarray(vector<int>& nums, int limit) {
map<int, int> m;
int ans = 0;
int i = 0;
for (int j = 0; j < nums.size(); j++) {
m[nums[j]]++;
while (m.rbegin()->first - m.begin()->first > limit) {
m[nums[i]]--;
if (m[nums[i]] == 0) {
m.erase(nums[i]);
}
i++;
}
ans = max(ans, j - i + 1);
}
return ans;
}