Problem: 918. 环形子数组的最大和
思路
和最大子数组和很类似,这种无后效性的问题一般可以通过DP来解决
解题方法
- 不存在环形,那么ans = maxS
- 最大子数组和位于环形中,那么剩余部门一定是连续子数组,且sum - maxS = minS
- 分别求出maxS, minS
- 需要特别注意,当数组元素均为负时,minS == sum,此时 sum - minS 其实是空,所以此时应该返回maxS
Code
class Solution {
public int maxSubarraySumCircular(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) sum += nums[i];
int min = minSubArray(nums);
int max = maxSubArray(nums);
if (sum == min) return max;
return Math.max(max, sum - min);
}
// 最小子数组和
public int minSubArray(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
dp[0] = nums[0];
int ans = dp[0];
for (int i = 1; i < n; i++) {
dp[i] = Math.min(nums[i], dp[i-1] + nums[i]);
ans = Math.min(ans, dp[i]);
}
return ans;
}
// 最大子数组和
public int maxSubArray(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
dp[0] = nums[0];
int ans = dp[0];
for (int i = 1; i < n; i++) {
dp[i] = Math.max(nums[i], dp[i-1] + nums[i]);
ans = Math.max(ans, dp[i]);
}
return ans;
}
}