LeetCode 918 環形子陣列的最大和

2022-08-10 06:30:11 字數 1396 閱讀 2141

給定乙個由整數陣列 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)

首先先思考乙個簡化問題:對乙個非環形陣列,我們如何求解它的非空子陣列的最大可能和?

很顯然,這個是動態規劃類題裡很經典的乙個問題 : 53. 最大子序和。我們可以通過動態規劃的思想,記錄位置i結尾的子串行的最大和為 dp[i],那麼第i個元素結尾的最大和可以表示為:dp[i] = num[i] + max(0, dp[i-1])。(原理是位置i的最大和,只可能是 num[i]  和  num[i] + dp[i-1]的其中乙個,如果dp[i-1]<0,則一定是num[i])。隨後通過迴圈累計就可以求出每個位置的最大和,每次求出來比較下即可。

而本問題是上述問題的乙個變種,它特殊就特殊在加了環形陣列這個條件之後,當陣列橫跨了陣列的起始點之後,計算dp變的複雜了。所以可以拆解成兩個問題:

1) 計算區間就在當前陣列本身內的最大可能和。這個簡單,就和上面提到的問題53的解決思路一樣。

2) 計算區間橫跨了陣列的起始點的情況。這個我們可以變通一下:環本身的總和 a 是固定的,求這種情況的最大值,可以轉化為求,陣列本身區間內的最小值,然後用 a - 這個最小值就可以了。

綜上,根據分析,我們可以得出解決思路了:按照題53的求解方式,去遍歷陣列,在遍歷過程中,求每個元素結尾的最大子串行和 summax最小子序列和 summin 。然後每一輪求 max(summax, a-summin) 去比較即可

要考慮乙個特殊情況:那就是陣列為單調負數的情況時,有可能會出現 a-summin = 0 的情況,這種情況是需要排除掉的(因為這是情況2的求解方式,但是a=summin的情況下,這個子串行就是陣列本身,並不符合橫跨的情況,需要排除)。

func maxsubarraysumcircular(a int) int 

if len(a) == 1

//2.從第乙個元素開始往後做推算

sum, summax, summin, prevmax, prevmin := a[0], a[0], a[0], a[0], a[0]

for i:=1; ib

return b

}func min (a, b int) int

return b

}

leetcode 918 環形子陣列的最大和

給定乙個由整數陣列 a 表示的環形陣列 c,求 c 的非空子陣列的最大可能和。子陣列要連續 important 因為是環形,所以我們可以分為兩種情況討論 對於第一種情況,先求出陣列的和,然後再再求出和最小的子陣列,用和減去它即可 對於第二種情況,我們直接求出和最大的子陣列 然後二者取最大值即可。和最...

leetcode 918 環形子陣列的最大和

918.環形子陣列的最大和 求兩個值,乙個是子陣列最小值,乙個是子陣列最大值 環形陣列如果沒有跨最後乙個那就是子陣列最大值 如果跨了最後乙個那就是 總數 子陣列最小值 為什麼是 total min 如果成環狀,那麼陣列將被分成兩段 頭和尾 總數是不變的,如果其他部分加起來最大,那麼中間的子陣列必然加...

918 環形子陣列的最大和

題目描述 給定乙個由整數陣列 a 表示的環形陣列 c,求 c 的非空子陣列的最大可能和。在此處,環形陣列意味著陣列的末端將會與開頭相連呈環狀。形式上,當0 i a.length 時 c i a i 且當 i 0 時 c i a.length c i 此外,子陣列最多只能包含固定緩衝區 a 中的每個元...