给定一个整数数组 arr 和一个整数 k ,通过重复 k 次来修改数组。
例如,如果 arr = [1, 2] , k = 3 ,那么修改后的数组将是 [1, 2, 1, 2, 1, 2] 。
返回修改后的数组中的最大的子数组之和。注意,子数组长度可以是 0,在这种情况下它的总和也是 0。
由于 结果可能会很大,需要返回的 109 + 7 的 模 。
示例 1:
输入:arr = [1,2], k = 3
输出:9
示例 2:
输入:arr = [1,-2,1], k = 5
输出:2
示例 3:
输入:arr = [-1,-2], k = 7
输出:0
class Solution {
public:
int kConcatenationMaxSum(vector<int>& arr, int k) {
int MOD = 1e9 + 7;
long long sum = 0;
long long maxAns = 0;
long long pre = 0, maxMid = 0;
for(int &num : arr){
sum += num;
maxAns = max(maxAns, sum);
pre = max(pre + num, (long long)num);
maxMid = max(maxMid, pre);
}
if(k == 1){
return maxMid % MOD;
}
//最大后缀和
long long maxAns2 = 0;
long long sum2 = 0;
for(int i = arr.size() - 1; i >= 0 ; i--){
sum2 += arr[i];
maxAns2 = max(maxAns2, sum2);
}
int theMax;
if(sum > 0){
theMax = max((k-2) * sum + maxAns + maxAns2, maxMid)%MOD;
}
else if(sum <= 0){
theMax = max(maxMid,maxAns + maxAns2)%MOD;
}
return theMax;
}
};
本题没有官解,也没有看到统一的比较好的题解。这道题主要是要考虑各种情况,可以先列出所有的情况,最后再进行代码优化,将类似的情况整理在一起。maxMid是最大子段和,使用的是Kadane算法,maxAns是最大前缀和,maxAns2是最大后缀和。首先如果当k为1的时候,最大子段和就是maxMid。接下来讨论sum的情况,如果sum>0,就要比较两种情况,一种是复制的2到k-1组元素的和加上第一组元素的最大后缀和再加上最后一组元素的最大前缀和,第二种情况是第一组元素中的最大子段和就是整个复制过的数组的最大子段和。当sum<=0的时候,也要比较两种情况哪个大,第一种是第一组元素中的最大子段和,第二种是最大前缀和加上最大后缀和(例如第一组元素的最大后缀和加上第二组元素的最大前缀和)。