『题目』:
给你一个整数数组 arr
和一个整数 k
。首先,我们要对该数组进行修改,即把原数组 arr
重复 k
次。举个例子,如果 arr = [1, 2]
且 k = 3
,那么修改后的数组就是 [1, 2, 1, 2, 1, 2]
。然后,请你返回修改后的数组中的最大的子数组之和。注意,子数组长度可以是 0
,在这种情况下它的总和也是 0
。由于 结果可能会很大,所以需要 模(mod) 10^9 + 7
后再返回。
『输入输出』
输入:arr = [1,2], k = 3
输出:9
输入:arr = [1,-2,1], k = 5
输出:2
输入:arr = [-1,-2], k = 7
输出:0
『题解』:
这道题目其实是放大版《最大连续子数组之和》,首先最简单的想法复制所有数组,然后做一次最大连续子数组和。但是发现并不需要,其实因为是循环的,假设给的数组长度为n
,数据为a[0]...a[n]
,假设sum=a[0] + a[1] + ...+ a[n]
,且sum > 0
,那么最理想的最大值,肯定是a[start] + ... + a[n] + (k - 2) * sum + (a[0] + a[1] + ... + a[end]
,所以这道题目就可以转化为找start
和end
。end
很好找,只要从0
开始进行不断累加,找到最大的字串即可。那么start
呢,就是跑一遍《最大连续子数组之和》,然后就可以加起来了。当然如果最大值是循环断开的,我的做法是复制一遍a
数组,数组长度变成了2 * n
,然后先做一次《最大连续子数组之和》,把最大值保留下来进行对比。
『实现』:
import java.util.Arrays;
public class test3 {
private static final long mod = 1000000007;
public int kConcatenationMaxSum(int[] arr, int k) {
long ans = 0;
if(arr == null || arr.length == 0 || k <= 0) return 0;
if(k == 1)
{
long[] dp = new long[arr.length];
dp[0] = arr[0];
ans = Math.max(ans,dp[0]);
for(int i = 1;i < arr.length;i++)
{
dp[i] = (dp[i - 1] + arr[i]) > arr[i] ? dp[i - 1] + arr[i] : arr[i];
ans = Math.max(ans,dp[i]);
}
ans = ans % mod;
}
else
{
int[] tmp = new int[arr.length * 2];
int[] bef = new int[arr.length * 2];
long[] dp = new long[arr.length * 2];
int bigind = -1; //最大连续串的标号
long sum = 0;
for(int i = 0;i < arr.length;i++)
{
tmp[i] = arr[i];
sum = sum + arr[i];
tmp[arr.length + i] = arr[i];
}
dp[0] = arr[0];
bef[0] = 0;
if(dp[0] > ans)
{
ans = dp[0];
bigind = 0;
}
for(int i = 1;i < tmp.length;i++)
{
if(dp[i - 1] + tmp[i] > tmp[i])
{
dp[i] = dp[i - 1] + tmp[i];
bef[i] = bef[i - 1];
}
else
{
dp[i] = tmp[i];
bef[i] = i;
}
if(ans <= dp[i])
{
ans = dp[i];
bigind = i;
}
}
if(bigind == -1) return 0;
if(k == 2) return (int) ans;
if(sum >0)
{
long tmpans = (dp[tmp.length - 1] % mod + (sum % mod * (k - 2 - 1) % mod) % mod) % mod ;
int tmpmax = 0;
int tmpsum = 0;
for(int i = 0; i < arr.length;i++)
{
tmpsum += arr[i];
tmpmax = Math.max(tmpmax,tmpsum);
}
ans = Math.max(ans,(tmpans + tmpmax) % mod);
}
}
return (int)ans;
}
public static void main(String[] args) {
test3 of = new test3();
int[] arr = {-5,-2,0,0,3,9,-2,-5,4};
System.out.println(of.kConcatenationMaxSum(arr,5));
}
}