918. Maximum Sum Circular Subarray(环形子数组的最大和)
题目大意
Given a circular integer array nums
of length n
, return the maximum possible sum of a non-empty subarray of nums
.
A circular array means the end of the array connects to the beginning of the array. Formally, the next element of nums[i]
is nums[(i + 1) % n]
and the previous element of nums[i]
is nums[(i - 1 + n) % n]
.
A subarray may only include each element of the fixed buffer nums
at most once. Formally, for a subarray nums[i], nums[i + 1], ..., nums[j]
, there does not exist i <= k1, k2 <= j
with k1 % n == k2 % n
.
中文释义
给定一个长度为 n
的环形整数数组 nums
,返回 nums
的非空子数组可能的最大和。
环形数组意味着数组的末端连接到数组的开头。形式上,nums[i]
的下一个元素是 nums[(i + 1) % n]
,前一个元素是 nums[(i - 1 + n) % n]
。
子数组最多只能包含固定缓冲 nums
中的每个元素一次。形式上,对于子数组 nums[i], nums[i + 1], ..., nums[j]
,不存在 i <= k1, k2 <= j
且 k1 % n == k2 % n
。
示例
- 示例 1:
- 输入:
nums = [1,-2,3,-2]
- 输出:
3
- 解释:子数组 [3] 有最大和 3。
- 输入:
- 示例 2:
- 输入:
nums = [5,-3,5]
- 输出:
10
- 解释:子数组 [5,5] 有最大和 5 + 5 = 10。
- 输入:
- 示例 3:
- 输入:
nums = [-3,-2,-3]
- 输出:
-2
- 解释:子数组 [-2] 有最大和 -2。
- 输入:
限制条件
n == nums.length
1 <= n <= 3 * 10^4
-3 * 10^4 <= nums[i] <= 3 * 10^4
解题思路
使用动态规划(DP)方法。分别计算非环形数组的最大子数组和和最小子数组和,以及数组总和。环形子数组的最大和可以是非环形的最大子数组和,或者是数组总和减去非环形的最小子数组和(如果整个数组的总和大于 0)。
步骤说明
- 初始化用于存储当前最大和、当前最小和、最大子数组和、最小子数组和和数组总和的变量。
- 遍历数组
nums
:- 更新当前最大和和最大子数组和。
- 更新当前最小和和最小子数组和。
- 更新数组总和。
- 如果最大子数组和大于 0,则返回最大子数组和和数组总和减去最小子数组和中的较大者。否则,返回最大子数组和。
代码
class Solution {
public:
int maxSubarraySumCircular(vector<int>& nums) {
int current_max_sum = 0, current_min_sum = 0;
int max_sum = nums[0], min_sum = nums[0], sum = 0;
for (int num : nums) {
current_max_sum = max(current_max_sum + num, num);
max_sum = max(current_max_sum, max_sum);
current_min_sum = min(current_min_sum + num, num);
min_sum = min(current_min_sum, min_sum);
sum += num;
}
return max_sum > 0 ? max(max_sum, sum - min_sum) : max_sum;
}
};