【題目】*1191. K 次串聯後最大子數組之和
53.最大子序和
*152. 乘積最大子數組
*1186. 刪除一次得到子數組最大和
*1191. K 次串聯後最大子數組之和
給你一個整數數組 arr 和一個整數 k。
首先,我們要對該數組進行修改,即把原數組 arr 重複 k 次。
舉個例子,如果 arr = [1, 2] 且 k = 3,那麼修改後的數組就是 [1, 2, 1, 2, 1, 2]。
然後,請你返回修改後的數組中的最大的子數組之和。
注意,子數組長度可以是 0,在這種情況下它的總和也是 0。
由於 結果可能會很大,所以需要 模(mod) 10^9 + 7 後再返回。
示例 1:
輸入:arr = [1,2], k = 3
輸出:9
示例 2:
輸入:arr = [1,-2,1], k = 5
輸出:2
示例 3:
輸入:arr = [-1,-2], k = 7
輸出:0
提示:
1 <= arr.length <= 10^5
1 <= k <= 10^5
-10^4 <= arr[i] <= 10^4
【解題思路1】
- k = 1: max = 最大子串
- k >= 1:
如果數組和>0:max = 最大後子串 + (k - 2)*數組和 + 最大前子串
如果數組和<=0:max = 最大後子串 + 最大前子串 - 最後max與最大子串做對比,取最大值
會因爲int類型溢出而解答錯誤
class Solution {
public long MaxSub(int[] arr, int len){
// 求最大子串
long maxEndNow = 0;
long maxSub = 0;
for(int i = 0; i < len; i++) {
maxEndNow = Math.max(maxEndNow + arr[i], 0);
maxSub = Math.max( maxSub, maxEndNow);
}
return maxSub;
}
public int kConcatenationMaxSum(int[] arr, int k) {
int i;
long sum, res;
long maxSub=0;
long maxPre=0;
long maxPost=0;
int len = arr.length;
if(arr == null || len == 0) {
return 0;
}
sum = 0;
// 得到數組和
for(i = 0; i < len; i++) {
sum = sum + arr[i];
}
// 得到最大前子串
sum = 0;
for(i = 0; i < len; i++) {
sum = sum + arr[i];
maxPre = Math.max( maxPre, sum);
}
// 得到最大後子串
sum = 0;
for(i = len - 1; i >= 0; i--) {
sum = sum + arr[i];
maxPost = Math.max( maxPost, sum);
}
// 得到最大子串
maxSub = MaxSub(arr, len);
if(k == 1) {
res = maxSub;
} else {
if(sum > 0) {
res = maxPost + (k - 2) * sum + maxPre;
} else {
res = maxPost + maxPre;
}
res = Math.max(res, maxSub);
}
return (int)res % 1000000007;
}
}
【解題思路2】動態規劃 - Kadane算法(待研究)
class Solution {
public int kConcatenationMaxSum(int[] arr, int k) {
if (arr == null || arr.length == 0){
return 0;
}
long maxOfEnd = arr[0] > 0 ? arr[0] : 0L;
long maxSoFar = maxOfEnd;
long sum = arr[0];
for (int i = 1; i < Math.min(k, 2) * arr.length; i++) {
maxOfEnd = Math.max(maxOfEnd + arr[i % arr.length], arr[i % arr.length]);
maxSoFar = Math.max(maxOfEnd, maxSoFar);
if (i < arr.length){
sum += arr[i];
}
}
while (sum > 0 && --k >= 2)
maxSoFar = (maxSoFar + sum) % 1000000007;
return (int) maxSoFar;
}
}