最大子數組和問題


(一)最大字數組和問題

  問題:給定n個整數(可能為負數)組成的序列a[1],a[2]…a[n],求該序列a[i],a[i+1]…a[j]的子段和的最大值。當所給整數均為負數的時候,定義子段和為0.《百度百科

  • 分析

  顯然問題可以在O(n2)的時間復雜度上解決,但是考慮到當n很大(比如1e9)時,O(n2)的時間復雜度並不能完美的解決這個問題。因此我們是否可以對O(n2)的代碼進行優化呢?答案是肯定的。
  不妨設,a[i],a[i+1]...a[j]已經是所求最大子數組和的部分前綴並且已知和為sum且當前最大子數組和為maxx,繼續考慮a[j+1]的情況,如果sum加上a[j+1]可以使和sum大於a[j+1],則更新sum的值為sum + a[i]反之更新sum的值為a[i]。由此我們可以得到遞推公式

sum = max(sum + a[i], a[i])

  當sum的值大於已知最大字數組和maxx的時候更新maxx即可。

  • Python代碼
import math

def fun(arr):
    n = len(arr)
    if n <= 0:
        return 0
    sum = 0
    maxx = 0
    
    for i in range(0, n):
        sum = max(sum + arr[i], arr[i])
        if sum >= maxx:
            maxx = sum
            
    return maxx

  代碼地址

  • 流程圖

算法流程圖

  • 單元測試

  接下來我們使用單元測試來測試一下代碼,一下是單元測試代碼:

import my_math, unittest

arr0 = []
arr1 = [-1, -2, -3, -4]
arr2 = [-2, 11, -4, 13, -2, -5]

class ProductTestCase(unittest.TestCase):
    def test0(self):
        p = my_math.fun(arr0)
        self.assertEqual(0, p, 'Worng Answer!')
    
    def test1(self):
        p = my_math.fun(arr1)
        self.assertEqual(0, p, 'Worng Answer!')
    
    def test2(self):
        p = my_math.fun(arr2)
        self.assertEqual(20, p, 'Worng Answer!')
        
if __name__=='__main__': unittest.main()

  本測試代碼實現了條件覆蓋,樣例數組arr0為空測試數組長度小於等於0的情況(實際小於0的情況不存在),arr1數組測試數組值全為負數時返回最大子數組和為0,arr2數組可以測試sum>=maxx的兩個條件。測試代碼結果如下:
測試結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM