918. 环形连续子数组的最大和
题目描述:
给定一个长度为 n 的环形整数数组 nums ,返回 nums 的非空 子数组 的最大可能和 。环形数组 意味着数组的末端将会与开头相连呈环状。形式上, nums[i] 的下一个元素是 nums[(i + 1) % n] , nums[i] 的前一个元素是 nums[(i - 1 + n) % n] 。子数组 最多只能包含固定缓冲区 nums 中的每个元素一次。形式上,对于子数组 nums[i], nums[i + 1], ..., nums[j] ,不存在 i <= k1, k2 <= j 其中 k1 % n == k2 % n 。
提示:
n == nums.length1 <= n <= 3 * 104-3 * 104 <= nums[i] <= 3 * 104
解题思路:
与常规求最大连续子数组和问题相比,该题多出来一种情况,那就是和最大的连续子数组在首尾处(如下图所示)。这种情况下,最大连续子数组和 = 数组总和 - 最小连续子数组和(也即图中空白处)

因此,为了方便起见,我直接用两次遍历来分别计算出常规的最大连续子数组和max以及常规的最小连续子数组和min,同时也统计数组总和sum。最后比较(max)与(sum-min)取较大值。由于题目要求不允许空子数组,因此在初始化时都设为数组的第一个值。若是允许空子数组,可以初始化为0。
class Solution { public int maxSubarraySumCircular(int[] nums) { int sum = 0; int max = nums[0]; int prev = 0; for(int i=0;i<nums.length;i++){ sum += nums[i]; //顺便计算数组总和 prev = Math.max(prev+nums[i],nums[i]); max = Math.max(max,prev); } prev = 0; int min = nums[0]; for(int i=0;i<nums.length;i++){ prev = Math.min(prev+nums[i],nums[i]); min = Math.min(min,prev); } if(sum != min){ max = Math.max(max,sum-min); } return max; //当最小子数组为整个数组时,sum-min会导致结果为0,因此这种情况就无需比较max和sum-min,直接返回max即可
} }
|
|

浙公网安备 33010602011771号