[LeetCode] 918. Maximum Sum Circular Subarray 環形子數組的最大和

2021-02-20 刷盡天下

Given a circular array C of integers represented by A, find the maximum possible sum of a non-empty subarray of C.

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.)

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.)

Example 1:

Input: [1,-2,3,-2]

Output: 3

Explanation: Subarray [3] has maximum sum 3

Example 2:

Input: [5,-3,5]

Output: 10 Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10

Example 3:

Input: [3,-1,2,-1]

Output: 4

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

Example 4:

Input: [3,-2,2,-3]

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

Example 5:

Input: [-2,-3,-1]

Output: -1 Explanation: Subarray [-1] has maximum sum -1

Note:

-30000<=A[i]<=30000

1<=A.length<=30000


這道題讓求環形子數組的最大和,對於環形數組,我們應該並不陌生,之前也做過類似的題目 Circular Array Loop,就是說遍歷到末尾之後又能回到開頭繼續遍歷。假如沒有環形數組這一個條件,其實就跟之前那道 Maximum Subarray 一樣,解法比較直接易懂。這裡加上了環形數組的條件,難度就增加了一些,需要用到一些 trick。既然是子數組,則意味著必須是相連的數字,而由於環形數組的存在,說明可以首尾相連,這樣的話,最長子數組的範圍可以有兩種情況,一種是正常的,數組中的某一段子數組,另一種是分為兩段的,即首尾相連的,可以參見 大神 lee215 的帖子 中的示意圖。對於第一種情況,其實就是之前那道題 Maximum Subarray 的做法,對於第二種情況,需要轉換一下思路,除去兩段的部分,中間剩的那段子數組其實是和最小的子數組,只要用之前的方法求出子數組的最小和,用數組總數字和一減,同樣可以得到最大和。兩種情況的最大和都要計算出來,取二者之間的較大值才是真正的和最大的子數組。但是這裡有個 corner case 需要注意一下,假如數組中全是負數,那麼和最小的子數組就是原數組本身,則求出的差值是0,而第一種情況求出的和最大的子數組也應該是負數,那麼二者一比較,返回0就不對了,所以這種特殊情況需要單獨處理一下,參見代碼如下:

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


類似題目:

Maximum Subarray

Circular Array Loop


參考資料:

https://leetcode.com/problems/maximum-sum-circular-subarray/

https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/178422/One-Pass


LeetCode All in One 題目講解匯總(持續更新中...)

相關焦點

  • [leetcode] 53. Maximum Subarray
    Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
  • 最大子序和(Maximum Subarray)
    Maximum Subarray給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。示例:輸入: [-2,1,-3,4,-1,2,1,-5,4]輸出: 6解釋: 連續子數組 [4,-1,2,1] 的和最大,為 6。
  • ​LeetCode刷題實戰53:最大子序和
    今天和大家聊的問題叫做 最大子序和,我們先來看題面:https://leetcode-cn.com/problems/maximum-subarray/Given an integer array nums, find the contiguous subarray (containing at least one number
  • LeetCode刷題第三周【數組(簡單)】
    至少是其他數字兩倍的最大數(難度:簡單)Oct.29 刷題請點擊或見附錄:747. 至少是其他數字兩倍的最大數[4]題目要求:在一個給定的數組nums中,總是存在一個最大元素 。查找數組中的最大元素是否至少是數組中每個其他數字的兩倍。
  • [LeetCode] 912. Sort an Array 數組排序
    Given an array of integers nums, sort the array in ascending
  • LeetCode數組類知識點&題型總結
    leetcode第一題就是two-sum,對於這類題目,首先看題目要求的時間複雜度和空間複雜度是什麼,其次看有沒有限制條件,如要求不能有重複的子數組或者要求按照升序/降序排列等。1.按start排序2.在前一個區間的end和後一個區間的start找交集例題:252 meeting room[easy](https://leetcode.com/problems/meeting-rooms/)題目理解:給定一個數組,包含每個會議的開始時間和結束時間[[s1,e1],[s2,e2],...]
  • Go 刷 leetcode|一道簡單難度卻讓我陷入沉思的題目
    題目描述 給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。示例:輸入: [-2,1,-3,4,-1,2,1,-5,4],輸出: 6解釋: 連續子數組 [4,-1,2,1] 的和最大,為 6。進階:如果你已經實現複雜度為 O(n) 的解法,嘗試使用更為精妙的分治法求解。
  • Split Array Largest Sum
    給定一個正整數數組nums, 將其分成m個子數組(子數組至少應該有一個元素),那麼每一次分的子數組中的元素求和,會有一個最大值,建設是sum。問題是求所有的分法中,sum最小的值是多少。題目中舉了一個例子。
  • 「LeetCode算法精講」數組中的最短無序連續子數組(Python)
    來源:力扣(LeetCode)連結:https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray解法效率LeetCode的Python執行用時隨緣,只要時間複雜度沒有明顯差異,執行用時一般都在同一個量級,僅作參考意義。
  • 【複試上機】LeetCode-簡單-013-Maximum Subarray
    13.Maximum Subarray 動態規劃 使用動態規劃需要的前提:最優子結構性質。 發現這個問題可以用動態規劃求解: 最優子結構性質 假設數組A的最大子序和對應一個連續元素組成的數組B。
  • 【Leetcode-Easy-53】Maximum Subarray
    解法一:O(n^2) public int maxSubArray(int[] nums) { int max = nums[0]; for(int i = 0; i < nums.length; i++){ int sum
  • [LeetCode] 923. 3Sum With Multiplicity 三數之和的多種情況
    因為有很多重複的數字,所以將相同的數字放在一起便於統計,可以對數組進行排序,然後遍歷數組,先確定一個數字 A[i],則只需要找另外兩個數字,使得其和為 sum = target-A[i]。然後使用兩個指針j和k分別初始化為 i+1 和 n-1,若 A[j]+A[k] 小於 sum,則將j自增1;若 A[j]+A[k] 大於 sum,則將k自減1;若 A[j]+A[k] 正好等於 sum,則此時需要統計重複數字的個數,假設跟 A[j] 相同的數字有 left 個,跟 A[k] 相同的數字有 right 個。
  • [LeetCode] 996. Number of Squareful Arrays 平方數組的個數
    Given an array A of non-negative integers, the array is squareful if for
  • 數據結構與算法:05 Leetcode同步練習(一)
    目錄題目01:兩數之和題目02:刪除排序數組中的重複項題目03:移除元素題目04:最大子序和題目05:盛最多水的容器題目06:搜索旋轉排序數組題目07:數組中的第K個最大元素題目08:除自身以外數組的乘積題目09:尋找兩個有序數組的中位數題目10:缺失的第一個正數
  • 2019/10/25-LeetCode Array (Day01)
    Maximum SubarrayGiven an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
  • [leetcode] 15. 3Sum
    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?(ie, a ≤ b ≤ c)The solution set must not contain duplicate triplets.
  • LeetCode:連續子數組的最大和
    輸入一個整型數組,數組中的一個或連續多個整數組成一個子數組。求所有子數組的和的最大值。
  • 一文看懂《最大子序列和問題》(內含Java,Python,JS代碼)
    也有原題《53.maximum-sum-subarray》,今天我們就來徹底攻克它。題目描述求取數組中最大連續子序列和,例如給定數組為 A = [1, 3, -2, 4, -5], 則最大連續子序列和為 6,即 1 + 3 +(-2)+ 4 = 6。去首先我們來明確一下題意。題目說的子數組是連續的題目只需要求和,不需要返回子數組的具體位置。數組中的元素是整數,但是可能是正數,負數和 0。