package com.algorithm.level2.dp;
// Kadane 算法
// 环形数组的子数组最大累加和
// 给定一个数组nums,长度为n
// nums是一个环形数组,下标0和下标n-1是连在一起的
// 返回环形数组中,子数组最大累加和
// 测试链接 : https://leetcode.cn/problems/maximum-sum-circular-subarray/
public class Level2_DP_019_MaximumSumCircularSubarray {
/**
* 核心思想
* 环形数组的最大子数组和可以通过以下两种情况得到:
* 非环形情况 :直接使用 Kadane 算法求解最大子数组和。
* 环形情况 :总和减去最小子数组和(即绕过中间部分)。
* 最终结果为两种情况中的较大值。
*
* @param nums
* @return
*/
public static int maxSubarraySumCircular(int[] nums) {
// 变量说明
// all:数组的总和。
// maxsum:非环形情况下,最大子数组的和。
// minsum:非环形情况下,最小子数组的和。
// maxpre 和 minpre:分别表示当前最大和最小子数组的累加和。
int n = nums.length, all = nums[0], maxsum = nums[0], minsum = nums[0];
for (int i = 1, maxpre = nums[0], minpre = nums[0]; i < n; i++) {
all += nums[i];
maxpre = Math.max(nums[i], nums[i] + maxpre);
maxsum = Math.max(maxsum, maxpre);
minpre = Math.min(nums[i], nums[i] + minpre);
minsum = Math.min(minsum, minpre);
}
// 1) maxsum
// 2) all - minsum
return all == minsum ? maxsum : Math.max(maxsum, all - minsum);
}
}