LeetCode #918 Maximum Sum Circular Subarray 環形子數組的最大和 918 Maximum Sum Circular Subarray 環形子數組的最大和

918 Maximum Sum Circular Subarray 環形子數組的最大和

Description:
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.

Example:

Example 1:

Input: nums = [1,-2,3,-2]
Output: 3
Explanation: Subarray [3] has maximum sum 3

Example 2:

Input: nums = [5,-3,5]
Output: 10
Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10

Example 3:

Input: nums = [3,-1,2,-1]
Output: 4
Explanation: Subarray [2,-1,3] has maximum sum 2 + (-1) + 3 = 4

Example 4:

Input: nums = [3,-2,2,-3]
Output: 3
Explanation: Subarray [3] and [3,-2,2] both have maximum sum 3

Example 5:

Input: nums = [-2,-3,-1]
Output: -1
Explanation: Subarray [-1] has maximum sum -1

Constraints:

n == nums.length
1 <= n <= 3 * 10^4
-3 * 10^4 <= nums[i] <= 3 * 10^4

題目描述:
給定一個由整數數組 A 表示的環形數組 C,求 C 的非空子數組的最大可能和。

在此處,環形數組意味着數組的末端將會與開頭相連呈環狀。(形式上,當0 <= i < A.length 時 C[i] = A[i],且當 i >= 0 時 C[i+A.length] = C[i])

此外,子數組最多隻能包含固定緩衝區 A 中的每個元素一次。(形式上,對於子數組 C[i], C[i+1], ..., C[j],不存在 i <= k1, k2 <= j 其中 k1 % A.length = k2 % A.length)

示例 :

示例 1:

輸入:[1,-2,3,-2]
輸出:3
解釋:從子數組 [3] 得到最大和 3

示例 2:

輸入:[5,-3,5]
輸出:10
解釋:從子數組 [5,5] 得到最大和 5 + 5 = 10

示例 3:

輸入:[3,-1,2,-1]
輸出:4
解釋:從子數組 [2,-1,3] 得到最大和 2 + (-1) + 3 = 4

示例 4:

輸入:[3,-2,2,-3]
輸出:3
解釋:從子數組 [3] 和 [3,-2,2] 都可以得到最大和 3

示例 5:

輸入:[-2,-3,-1]
輸出:-1
解釋:從子數組 [-1] 得到最大和 -1

提示:

-30000 <= A[i] <= 30000
1 <= A.length <= 30000

思路:

參考LeetCode #53 Maximum Subarray 最大子序和
遍歷數組的同時, 記錄數組當前的最大值/最小值和子序和的最大值/最小值, 以及數組的和
如果數組中的值都是負的則直接返回數組的最大值
否則返回子序和的最大值數組和與子序和的最小值的差中較大的那個
上述兩個值分別對應最大子序和及跨越邊界的最大子序和
時間複雜度爲 O(n), 空間複雜度爲 O(1)

代碼:
C++:

class Solution 
{
public:
    int maxSubarraySumCircular(vector<int>& nums) 
    {
        int n = nums.size(), cur_max = nums.front(), max_value = nums.front(), cur_min = nums.front(), min_value = nums.front(), s = accumulate(nums.begin(), nums.end(), 0);
        for (int i = 1; i < n; i++) 
        {
            cur_max = cur_max > 0 ? cur_max + nums[i] : nums[i];
            max_value = max(max_value, cur_max);
            cur_min = cur_min < 0 ? cur_min + nums[i] : nums[i];
            min_value = min(min_value, cur_min);
        }
        return max_value < 0 ? max_value : max(max_value, s - min_value);
    }
};

Java:

class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int n = nums.length, curMax = nums[0], maxValue = nums[0], curMin = nums[0], minValue = nums[0], s = nums[0];
        for (int i = 1; i < n; i++) {
            s += nums[i];
            curMax = curMax > 0 ? curMax + nums[i] : nums[i];
            maxValue = Math.max(maxValue, curMax);
            curMin = curMin < 0 ? curMin + nums[i] : nums[i];
            minValue = Math.min(minValue, curMin);
        }
        return maxValue < 0 ? maxValue : Math.max(maxValue, s - minValue);
    }
}

Python:

class Solution:
    def maxSubarraySumCircular(self, nums: List[int]) -> int:
        cur_max = max_value = cur_min = min_value = s = nums[0]
        for i in range(1, len(nums)):
            s += nums[i]
            max_value, min_value = max((cur_max := cur_max + nums[i] if cur_max > 0 else nums[i], max_value)), min((cur_min := cur_min + nums[i] if cur_min < 0 else nums[i]), min_value)
        return max_value if max_value < 0 else max(max_value, s - min_value)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章