Given a circular array C of integers represented by A
, find the maximum possible sum of a non-empty subarray of C.html
Here, a circular array means the end of the array connects to the beginning of the array. (Formally, C[i] = A[i]
when 0 <= i < A.length
, and C[i+A.length] = C[i]
when i >= 0
.)git
Also, a subarray may only include each element of the fixed buffer A
at most once. (Formally, for a subarray C[i], C[i+1], ..., C[j]
, there does not exist i <= k1, k2 <= j
with k1 % A.length = k2 % A.length
.)github
Example 1:數組
Input: [1,-2,3,-2] Output: 3 Explanation: Subarray [3] has maximum sum 3
Example 2:oop
Input: [5,-3,5] Output: 10 Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10
Example 3:code
Input: [3,-1,2,-1] Output: 4 Explanation: Subarray [2,-1,3] has maximum sum 2 + (-1) + 3 = 4
Example 4:orm
Input: [3,-2,2,-3] Output: 3 Explanation: Subarray [3] and [3,-2,2] both have maximum sum 3
Example 5:htm
Input: [-2,-3,-1] Output: -1 Explanation: Subarray [-1] has maximum sum -1
Note:blog
-30000 <= A[i] <= 30000
1 <= A.length <= 30000
這道題讓求環形子數組的最大和,對於環形數組,咱們應該並不陌生,以前也作過相似的題目 Circular Array Loop,就是說遍歷到末尾以後又能回到開頭繼續遍歷。假如沒有環形數組這一個條件,其實就跟以前那道 Maximum Subarray 同樣,解法比較直接易懂。這裏加上了環形數組的條件,難度就增長了一些,須要用到一些 trick。既然是子數組,則意味着必須是相連的數字,而因爲環形數組的存在,說明能夠首尾相連,這樣的話,最長子數組的範圍能夠有兩種狀況,一種是正常的,數組中的某一段子數組,另外一種是分爲兩段的,即首尾相連的,能夠參見 大神 lee215 的帖子 中的示意圖。對於第一種狀況,其實就是以前那道題 Maximum Subarray 的作法,對於第二種狀況,須要轉換一下思路,除去兩段的部分,中間剩的那段子數組實際上是和最小的子數組,只要用以前的方法求出子數組的最小和,用數組總數字和一減,一樣能夠獲得最大和。兩種狀況的最大和都要計算出來,取兩者之間的較大值纔是真正的和最大的子數組。可是這裏有個 corner case 須要注意一下,假如數組中全是負數,那麼和最小的子數組就是原數組自己,則求出的差值是0,而第一種狀況求出的和最大的子數組也應該是負數,那麼兩者一比較,返回0就不對了,因此這種特殊狀況須要單獨處理一下,參見代碼以下:ci
class Solution { public: int maxSubarraySumCircular(vector<int>& A) { int sum = 0, mn = INT_MAX, mx = INT_MIN, curMax = 0, curMin = 0; for (int num : A) { curMin = min(curMin + num, num); mn = min(mn, curMin); curMax = max(curMax + num, num); mx = max(mx, curMax); sum += num; } return (sum - mn == 0) ? mx : max(mx, sum - mn); } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/918
相似題目:
參考資料:
https://leetcode.com/problems/maximum-sum-circular-subarray/
https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/178422/One-Pass