【最佳解法】剑指 Offer 42. 连续子数组的最大和
我是小張同學(xué),立志用最簡潔的代碼做最高效的表達(dá)
思路:動態(tài)規(guī)劃
假設(shè)nums\textit{nums}nums 數(shù)組的長度是 nnn,下標(biāo)從 000 到 n?1n-1n?1。
我們用 f(i)f(i)f(i)代表以第 ii 個數(shù)結(jié)尾的「連續(xù)子數(shù)組的最大和」,因此我們只需要求出每個位置的 f(i)f(i),然后返回 ff 數(shù)組中的最大值即可。那么我們?nèi)绾吻?f(i)f(i)f(i)呢?我們可以考慮 nums[i]\textit{nums}[i]nums[i] 單獨(dú)成為一段還是加入 f(i?1)f(i-1)f(i?1) 對應(yīng)的那一段,這取決于$ \textit{nums}[i]$ 和 f(i?1)+nums[i]ff(i-1) + \textit{nums}[i]ff(i?1)+nums[i]f 的大小,我們希望獲得一個比較大的,于是可以寫出這樣的動態(tài)規(guī)劃轉(zhuǎn)移方程:
f(i)=max?{f(i?1)+nums[i],nums[i]}f(i) = \max \{ f(i-1) + \textit{nums}[i], \textit{nums}[i] \}f(i)=max{f(i?1)+nums[i],nums[i]}
不難給出一個時間復(fù)雜度 O(n)O(n)O(n)、空間復(fù)雜度 O(n)O(n)O(n) 的實(shí)現(xiàn),即用一個 ff 數(shù)組來保存 f(i)f(i)f(i) 的值,用一個循環(huán)求出所有 f(i)f(i)f(i)。考慮到 f(i)f(i)f(i) 只和 f(i?1)f(i-1)f(i?1) 相關(guān),于是我們可以只用一個變量 pre\textit{pre}pre來維護(hù)對于當(dāng)前 f(i)f(i)f(i) 的 f(i?1)f(i-1)f(i?1) 的值是多少,從而讓空間復(fù)雜度降低到 O(1)O(1)O(1),這有點(diǎn)類似「滾動數(shù)組」的思想。
class Solution {public int maxSubArray(int[] nums) {if(nums.length == 0) return 0;int fin = nums[0], max = nums[0];for(int i = 1; i < nums.length; i++) {if(max <= 0) max = nums[i];else max += nums[i];if(max > fin) fin = max;}return fin;} }有志者,事竟成,破釜沉舟,百二秦關(guān)終屬楚。
苦心人,天不負(fù),臥薪嘗膽,三千越甲可吞吳。
總結(jié)
以上是生活随笔為你收集整理的【最佳解法】剑指 Offer 42. 连续子数组的最大和的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【三万字!】Dubbo、Zookeepe
- 下一篇: 剑指 Offer 43. 1~n 整数中