题意:
给定一个由整数数组 A 表示的环形数组 C,求 C 的非空子数组的最大可能和。子数组要连续!important;
题解:
因为是环形,所以我们可以分为两种情况讨论
- 包含两段
- 只包含一段
对于第一种情况,先求出数组的和,然后再再求出和最小的子数组,用和减去它即可
对于第二种情况,我们直接求出和最大的子数组
然后二者取最大值即可。
和最小的子数组 && 和最大的子数组
d
p
[
i
]
=
m
a
x
(
d
p
[
i
−
1
]
+
a
[
i
]
,
a
[
i
]
)
dp[i] = max(dp[i-1]+a[i], a[i])
dp[i]=max(dp[i−1]+a[i],a[i])
最小子数组就把原数组取反再求最大子数组即可~
/**
* @param {number[]} A
* @return {number}
*/
var maxSubarraySumCircular = function(A) {
let sum = 0;
A.forEach(v => sum += v);
let dp = new Array(A.length).fill(0);
ans = -Infinity;
let ex = -Infinity;
for(let i = 0; i < A.length; i++) {
dp[i] = A[i];
if(i > 0) dp[i] = Math.max(dp[i-1] + A[i], dp[i]);
ans = Math.max(dp[i],ans);
ex = Math.max(ex,A[i]);
}
for(let i = 0; i < A.length; i++) A[i] = -A[i];
dp.fill(0);
let pl = -Infinity;
for(let i = 0; i < A.length; i++) {
dp[i] = A[i];
if(i > 0) dp[i] = Math.max(dp[i-1] + A[i], dp[i]);
pl = Math.max(pl,dp[i]);
}
ans = Math.max(ans, sum + pl);
if(ans === 0) ans = ex;
return ans;
};