【題目】
給你一個(gè)整數(shù)數(shù)組 nums ,請(qǐng)你找出一個(gè)具有最大和的連續(xù)子數(shù)組(子數(shù)組最少包含一個(gè)元素),返回其最大和。
子數(shù)組 是數(shù)組中的一個(gè)連續(xù)部分。
示例 1:
輸入: nums = [-2,1,-3,4,-1,2,1,-5,4]
輸出: 6
解釋: 連續(xù)子數(shù)組 [4,-1,2,1] 的和最大,為 6 。
示例 2:
輸入: nums = [1]
輸出: 1
示例 3:
輸入: nums = [5,4,-1,7,8]
輸出: 23
提示:
1 <= nums.length <= 105-104 <= nums[i] <= 104
進(jìn)階: 如果你已經(jīng)實(shí)現(xiàn)復(fù)雜度為 O(n) 的解法,嘗試使用更為精妙的 分治法 求解。
【題目解析】
解題方法
動(dòng)態(tài)規(guī)劃是解決最大子數(shù)組和問(wèn)題的一種高效方法。這種方法的核心思想是,對(duì)于數(shù)組中的每一個(gè)元素,我們都決定其是單獨(dú)構(gòu)成子數(shù)組還是與前面的子數(shù)組合并,以此來(lái)確保最大的子數(shù)組和。
-
狀態(tài)定義:定義
dp[i]為以nums[i]結(jié)尾的最大子數(shù)組和。 -
狀態(tài)轉(zhuǎn)移:
dp[i]可以從dp[i-1] + nums[i](如果加入當(dāng)前元素到前一個(gè)子數(shù)組中能得到更大的和)或nums[i](如果當(dāng)前元素單獨(dú)構(gòu)成子數(shù)組更優(yōu))中取較大值。 -
初始化:
dp[0] = nums[0],因?yàn)樽畛醯淖畲笞訑?shù)組和就是數(shù)組的第一個(gè)元素。 -
結(jié)果:整個(gè)數(shù)組的最大子數(shù)組和就是
dp數(shù)組中的最大值。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
# 如果數(shù)組為空,則直接返回0
if not nums:
return 0
# 初始化dp數(shù)組,dp[i]表示以nums[i]結(jié)尾的最大子數(shù)組和
dp = [0] * len(nums)
dp[0] = nums[0] # 第一個(gè)元素的最大子數(shù)組和就是它自己
# 遍歷數(shù)組,填充dp數(shù)組
for i in range(1, len(nums)):
# 狀態(tài)轉(zhuǎn)移方程:dp[i] = max(dp[i-1] + nums[i], nums[i])
# 解釋:對(duì)于每個(gè)位置i,可以選擇加入到前面的子數(shù)組中(如果dp[i-1]對(duì)結(jié)果有增益的話)
# 或者自己?jiǎn)为?dú)成為一個(gè)子數(shù)組(如果dp[i-1]是負(fù)數(shù)的話)
dp[i] = max(dp[i-1] + nums[i], nums[i])
# 返回dp數(shù)組中的最大值,即為整個(gè)數(shù)組的最大子數(shù)組和
return max(dp)
執(zhí)行效率

【總結(jié)】
適用問(wèn)題類型
最大子數(shù)組和問(wèn)題屬于動(dòng)態(tài)規(guī)劃領(lǐng)域中的優(yōu)化問(wèn)題,適用于需要找出最優(yōu)解(在本問(wèn)題中是最大和)的連續(xù)子序列問(wèn)題。動(dòng)態(tài)規(guī)劃法廣泛應(yīng)用于各類優(yōu)化問(wèn)題,尤其是那些可以通過(guò)解決子問(wèn)題來(lái)逐步構(gòu)建最終解的場(chǎng)景。
解決算法:動(dòng)態(tài)規(guī)劃
算法描述:動(dòng)態(tài)規(guī)劃方法通過(guò)將問(wèn)題分解為一系列相互關(guān)聯(lián)的子問(wèn)題,逐個(gè)解決子問(wèn)題,并利用子問(wèn)題的解來(lái)構(gòu)建全局最優(yōu)解。在最大子數(shù)組和問(wèn)題中,動(dòng)態(tài)規(guī)劃用于計(jì)算以每個(gè)元素結(jié)尾的最大子數(shù)組和,從而找到全局最大和。
-
算法特點(diǎn):
- 優(yōu)化子結(jié)構(gòu):?jiǎn)栴}的最優(yōu)解包含其子問(wèn)題的最優(yōu)解。
-
重疊子問(wèn)題:?jiǎn)栴}的分解涉及到重復(fù)求解子問(wèn)題,動(dòng)態(tài)規(guī)劃通過(guò)記憶化(或使用
dp數(shù)組)來(lái)優(yōu)化重復(fù)計(jì)算。 - 狀態(tài)轉(zhuǎn)移:通過(guò)定義狀態(tài)轉(zhuǎn)移方程來(lái)描述問(wèn)題的結(jié)構(gòu),關(guān)鍵在于如何選擇和定義狀態(tài)。
時(shí)間復(fù)雜度與空間復(fù)雜度
-
時(shí)間復(fù)雜度:
O(n),其中n是數(shù)組長(zhǎng)度。動(dòng)態(tài)規(guī)劃算法通過(guò)僅遍歷數(shù)組一次來(lái)計(jì)算所有子問(wèn)題的解,實(shí)現(xiàn)了高效的解決方案。 -
空間復(fù)雜度:
O(n)用于存儲(chǔ)dp數(shù)組。通過(guò)狀態(tài)壓縮技巧,可以將空間復(fù)雜度優(yōu)化到O(1),即只用有限的變量存儲(chǔ)必要的狀態(tài)。
實(shí)踐意義
- 算法學(xué)習(xí)與理解:最大子數(shù)組和問(wèn)題是學(xué)習(xí)動(dòng)態(tài)規(guī)劃方法的經(jīng)典例題,幫助理解動(dòng)態(tài)規(guī)劃的核心概念和實(shí)現(xiàn)方法。
- 軟件開(kāi)發(fā)中的應(yīng)用:動(dòng)態(tài)規(guī)劃法在軟件開(kāi)發(fā)中有廣泛應(yīng)用,特別是在需要處理復(fù)雜數(shù)據(jù)結(jié)構(gòu)和優(yōu)化性能的場(chǎng)合,如文本處理、圖像分析等。
- 解決實(shí)際問(wèn)題的能力:掌握動(dòng)態(tài)規(guī)劃不僅能解決特定的算法題目,更能在遇到實(shí)際問(wèn)題時(shí)快速設(shè)計(jì)出高效的解決方案,提高問(wèn)題解決的效率和質(zhì)量。
通過(guò)詳細(xì)分析最大子數(shù)組和問(wèn)題的動(dòng)態(tài)規(guī)劃解法,我們可以更深入地理解動(dòng)態(tài)規(guī)劃的工作原理和應(yīng)用范圍,為解決更復(fù)雜的問(wèn)題打下堅(jiān)實(shí)的基礎(chǔ)。