(一)最大字數組和問題
問題:給定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的兩個條件。測試代碼結果如下: