环形数组就是遍历到末尾之后又能回到开头继续遍历。既然是子数组,则意味着必须是相连的数字,而由于环形数组的存在,说明可以首尾相连,而且题目说明每个数字只能用一次。

1 public int maxSubarraySumCircular(int[] A) {
2 int maxTillHere = A[0];// 到目前为止的最大和
3 int maxInTotal = A[0];// 全局最大的连续子数组之和
4 int minTillHere = A[0];// 到目前为止的最小和
5 int minInTotal = A[0];// 全局最小的连续子数组之和
6 int sum = A[0];// 所有元素之和
7
8 for (int i = 1; i < A.length; i++) {
9 sum += A[i];
10 // 求最大连续子数组之和
11 if (maxTillHere + A[i] > A[i]) {// Kadane算法
12 maxTillHere += A[i];
13 } else {
14 maxTillHere = A[i];// 开始下一个连续子数组
15 }
16 maxInTotal = Math.max(maxInTotal, maxTillHere); // 更新全局最大
17
18 // 求最小连续子数组之和
19 if (minTillHere + A[i] < A[i]) {
20 minTillHere += A[i];
21 } else {
22 minTillHere = A[i];
23 }
24 minInTotal = Math.min(minInTotal, minTillHere);// 更新全局最小
25 }
26
27 if (sum == minInTotal) return maxInTotal;// 都是负数
28 return Math.max(sum - minInTotal, maxInTotal);// 都是正数,或有正有负的情况
29 }
文章转载自程序媛的梦想,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




