題目:給定一個整數數組 nums
,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
示例:
輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子數組 [4,-1,2,1] 的和最大,爲 6。
解法一:暴力破解法 時間複雜度O(N^3) 超時
這是我們最容易想到的,通過枚舉暴力破解,但是時間複雜度過高,算法運行超時。
def maxSubArray1(nums):
maxnum = pow(-2, 31)#最小的整數
for i in range(len(nums)):
for j in range(i,len(nums)):
sumnum = 0
for k in range(i,j+1):
sumnum += nums[k]
if sumnum > maxnum:
maxnum = sumnum
return maxnum
解法二:改進暴力破解法 時間複雜度O(N^2) 依然超時,看來題目要求是O(N)的時間複雜度
def maxSubArray2(nums):
maxnum = pow(-2, 31) # 最小的整數
for i in range(len(nums)):
sumnum = 0
for j in range(i, len(nums)):
sumnum += nums[j]
if sumnum > maxnum:
maxnum = sumnum
return maxnum
解法三:掃描法O(N)
我們可以從正負數入手,當我們加上一個正數時,和會增加;當我們加上一個負數時,和會減少。所以我們需要判斷當前的和是正數還是負數,如果是正數繼續向下累加,如果是負數,應該拋棄當前數重新開始加和。(據說這個算法是一個統計學家提出的,證明)
def maxSubArray3(nums):
current = nums[0] # 設置的初始值
sum = 0
for i in range(len(nums)):
if sum > 0:
sum += nums[i]
else:
sum = nums[i]
if sum > current:
current = sum
return current
解法四:
動態規劃知識點
定義:Dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems,solving each of those subproblems just once,and storing their solutions.
基本思想:一般來說,只要問題可以劃分爲規模更小的字問題,並且原問題的最優解中包含了子問題的最優解,則可以考慮用動態規劃解決。動態規劃的實質是分治思想和解決冗餘。因此,動態規劃是一種將問題實例分解爲更小的/相似的子問題,並存儲子問題的解,使得每個子問題只求解一次,最終獲得原問題的答案,以解決最優化問題的算法策略。
思想:我們遍歷nums數組,求出對應下標的最大連續子數組的和,並且保存在nums數組中。假設nums[i]是以第i個元素結尾的最大的連續子數組的和,這樣對於i之前的元素對應的最大連續子數組的長度都已經求得了。我們只需要判斷nums[i] + nums[i-1] 是否大於nums[i],將兩者中較大的值作爲nums[i]的值即可。如此迭代,即可得到整個數組每個元素對應的最大連續子數組和。
def maxSubArray4(nums):
length = len(nums)
for i in range(1,length):
subMaxSum = max(nums[i] + nums[i-1],nums[i])
nums[i] = subMaxSum
return max(nums)
參考鏈接:
1、https://blog.csdn.net/zwzsdy/article/details/80029796
2、https://blog.csdn.net/qq_27480345/article/details/86095087
3、https://blog.csdn.net/iva_brother/article/details/84037050