题目描述:
给你一个整数数组 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
我感觉比赛的时候思路是没有问题的,首先应该判断每个里面是不是都大于等于0,如果满足,那么就是sum*k(sum表示的是一个arr之和),如果不是的话,判断arr中是不是所有的数字都小于0,如果都小于0那么返回0,如果sum大于0,那么需要考虑的是将两个拼接起来,然后用dp求和,将后面(k-2)*sum然后加入到拼接两个吼的大小
class Solution {
public int kConcatenationMaxSum(int[] arr, int k) {
int sum = 0;
boolean isallminus = false;
boolean isalldayuze = true;
for (int i : arr) {
sum += i;
if(i > 0){
isallminus = true;
}
if(i < 0){
isalldayuze = false;
}
}
if(!isallminus){
return 0;
}
long result = 0;
long mod = 100000000 + 7;
// 每个数字都大于等于0,那么总和就是所有加起来
for (int i = 0; i < k; i++) {
result += sum;
result %= mod;
}
if(isalldayuze){
return (int) result;
}
// 先计算将所有可能的情况都扩展一遍
long tem1 = 0;
for (int i = 0; i < k; i++) {
tem1 += sum;
tem1 %= mod;
}
// 扩展一个即可
int [] temarray = new int[arr.length * 2];
for (int i = 0; i < temarray.length; i++) {
temarray[i] = arr[i % arr.length];
}
long tem2 = 0;
long [] dp = new long[temarray.length];
dp[0] = temarray[0];
for (int i = 1; i < dp.length; i++) {
if(dp[i - 1] < 0){
dp[i] = temarray[i];
continue;
}else {
dp[i] = dp[i - 1] + temarray[i];
dp[i] %= mod;
}
}
for (long l : dp) {
tem2 = Math.max(l, tem2);
}
if(sum > 0){
for (int i = 0; i < k - 2; i++) {
tem2 += sum;
tem2 %= mod;
}
}
return (int) Math.max(tem2, Math.max(tem1, result));
}
}
感觉我的代码还是有点问题的,虽然你连接了两个来取出最大值,但是你没有考虑拼接后面的因此有点问题:
看看别人AC的代码
class Solution {
public int kConcatenationMaxSum(int[] arr, int k) {
long sum = 0;
for (int a: arr) sum += a;
int mod = 1000000007;
long res = 0;
int n = arr.length;
int[] dp = new int[n+1];
for (int i = 0; i < n; i++) {
dp[i + 1] = Math.max(dp[i] + arr[i], arr[i]);
res = Math.max(res, dp[i+1]);
}
if (k == 1)
return (int) (res % mod);
long first = arr[0];
int cur = 0;
for (int i = 0; i < n; i++) {
cur += arr[i];
first = Math.max(first, cur);
}
System.out.println(dp[n]);
res = Math.max(res, first + dp[n]);
if (sum > 0) {
long tmp = sum * (k - 2) + dp[n] + first;
res = Math.max(res, tmp);
}
return (int) (res % mod);
}
}