环形子数组的最大和
难度:
标签:
题目描述
代码结果
运行时间: 61 ms, 内存: 20.0 MB
/*
* 思路:
* 1. 使用Stream计算总和、标准最大子数组和和最小子数组和。
* 2. 使用Stream的reduce方法来简化计算。
* 3. 特殊情况处理:如果最大子数组和小于0,返回最大子数组和。
*/
import java.util.Arrays;
public class Solution {
public int maxSubarraySumCircular(int[] nums) {
int totalSum = Arrays.stream(nums).sum();
int maxSum = Arrays.stream(nums).reduce(Integer.MIN_VALUE, (max, num) -> Math.max(max + num, num));
int currentMax = 0;
for (int num : nums) {
currentMax = Math.max(currentMax + num, num);
maxSum = Math.max(maxSum, currentMax);
}
int minSum = Arrays.stream(nums).reduce(Integer.MAX_VALUE, (min, num) -> Math.min(min + num, num));
int currentMin = 0;
for (int num : nums) {
currentMin = Math.min(currentMin + num, num);
minSum = Math.min(minSum, currentMin);
}
if (maxSum < 0) {
return maxSum;
}
return Math.max(maxSum, totalSum - minSum);
}
}
解释
方法:
此题解通过考虑两种情况来寻找最大子数组和:1. 子数组不包含环形的部分,即子数组完全位于数组的一个连续部分内。2. 子数组包含环形的部分,即子数组的一部分在数组的开头,另一部分在数组的结尾。对于第一种情况,直接使用Kadane算法找到最大子数组和。对于第二种情况,计算整个数组的总和,然后使用Kadane算法寻找非循环部分的最小子数组和,从总和中减去这个最小值,得到环形的最大子数组和。最后,比较这两种情况下的最大值,返回较大者。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在计算环形子数组的最大和时,需要从总和中减去非环形部分的最小子数组和?
▷🦆
在此题解中,若数组全部元素为负数,使用Kadane算法寻找最小子数组和是否会影响最终结果?
▷🦆
在计算非环形部分的最小子数组和时,为什么选择跳过数组的首尾元素?
▷🦆
在题解中,如何确保减去的非环形部分最小子数组和不是整个数组的总和,即确保子数组不为空?
▷