国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

動態規劃:8行代碼搞定最大子數組和問題

算法與數據結構 ? 來源:碼農的荒島求生 ? 作者:碼農的荒島求生 ? 2022-04-01 10:24 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

鐵子們,我是小風哥,你也可以叫我島主

今天給大家帶來一道極其經典的題目,叫做最大和子數組,給定一個數組,找到其中的一個連續子數組,其和最大。

示例:

輸入:nums=[-2,1,-3,4,-1,2,1,-5,4]
輸出:6
解釋:子數組[4,-1,2,1]的和為6,其它任何連續的子數組和不超過6.

想一想該怎樣解決這個問題。

如果你一時想不到解法可以從暴利解法開始。

暴力求解

這種解法最簡單,我們把所有子數組找出來,然后依次計算其和,找出一個最大的出來,比如給定數組[1,2,3],那么我們能找出子數組:[1],[2],[3],[1,2],[2,3],[1,2,3],很顯然這里和最大的子數組為[1,2,3],其值為6。

intsum(vector&nums,intb,inte){
intres=0;
for(;b<=?e;?b++)?{
????????res?+=?nums[b];
????}
????returnres;
}
intmaxSubArray(vector&nums){
intsize=nums.size();
intres=0x80000000;
for(inti=0;ifor(intj=i;jreturnres;
}

這種解法最簡單,該算法的時間復雜度為O(n^3),其中找出所有子數組的時間復雜度為O(n^2),計算每個子數組的和的時間復雜度為O(n),因此其時間復雜度為O(n^3)。

讓我們再來看一下這個過程,這里的問題在于計算每個子數組的和時有很多重復計算,比如我們知道了子數組[1,2]的和后再計算數組[1,2,3]的值時完全可以利用子數組[1,2]的計算結果而無需從頭到尾再算一遍,也就是說我們可以利用上一步的計算結果,這本身就是動態規劃的思想。

8589ba58-b15c-11ec-aa7f-dac502259ad0.png

基于該思想我們可以對上述代碼簡單改造一下:

intmaxSubArray(vector&nums){
intsize=nums.size();
intres=0x80000000;
for(inti=0;ifor(intj=i+1;jreturnres;
}

看到了吧,代碼不但更簡潔,而且運行速度更快,該算法的時間復雜度為O(n^2),比第一種解法高了很多。

還有沒有進一步提高的空間呢?

答案是肯定的。

分而治之

我們在之前的文章中說過,分治也是一種非常強大的思想,具體應該這里的話我們可以把整個數組一分為二,然后子數組也一分為二,不斷劃分下去就像這樣:

859b978c-b15c-11ec-aa7f-dac502259ad0.png

然后呢?

然后問題才真正開始有趣起來,注意,當我們劃分到最下層的時候,也就是不可再劃分時會得到兩個數組元素,比如對于數組[1,2]會劃分出[1]與[2],此時[1]與[2]不可再劃分,那么對于子問題[1,2],其最大子數組的和為max(1+2, 1,2),也就是說要么是左半部分的元素值、要么是右半部分的元素值、要么是兩個元素的和,就這樣我們得到了最后兩層的答案:

85bb2606-b15c-11ec-aa7f-dac502259ad0.png

假設對于數組[1,2,3,4],一次劃分后得到了[1,2]與[3,4],用上面的方法我們可以分別知道這兩個問題的最大子數組和,我們怎樣利用上述的答案來解決更大的問題,也就是[1,2,3,4]呢?

很顯然,對于[1,2,3,4]來說,最大子數組的和要么來自左半部分、要么來自右半部分、要么來自中間部分——也就是包含2和3,其中左半部分和右半部分的答案我們有了,那么中間部分的最大和該是多少呢?

其實這個問題很簡單,我們從中間開始往兩邊不斷累加,然后記下這個過程的最大值,比如對于[1,-2,3,-4,5],我們從中間的3開始先往左邊累加和是:{1+(-2)+3, (-2)+3, 3}也就是{2,1,3},因此我們以中間數字為結尾的最大子數組和為3:

85ce2bde-b15c-11ec-aa7f-dac502259ad0.png

另一邊也是同樣的道理,只不過這次是以中間數字為起點向右累加:

85e0d090-b15c-11ec-aa7f-dac502259ad0.png

然后這三種情況中取一個最大值即可,這樣我們就基于子問題解決了更大的問題:

85f977a8-b15c-11ec-aa7f-dac502259ad0.png

此后的道理一樣,最終我們得到了整個問題的解。

根據上面的分析就可以寫代碼了:

intgetMaxSum(vector&nums,intb,inte){
if(b==e)returnnums[b];
if(b==e-1)returnmax(nums[b],max(nums[e],nums[b]+nums[e]));
intm=(b+e)/2;
intmaxleft=nums[m];
intmaxright=nums[m];
intsum=nums[m];

for(inti=m+1;i<=?e;?i++)?{
????????sum?+=?nums[i];
????????maxright?=?max(maxright,?sum);
????}

????sum?=?nums[m];
????for(inti=m-1;i>=b;i--){
sum+=nums[i];
maxleft=max(maxleft,sum);
}
returnmax(getMaxSum(nums,b,m-1),max(getMaxSum(nums,m+1,e),maxleft+maxright-nums[m]));
}
intmaxSubArray(vector&nums){
returngetMaxSum(nums,0,nums.size()-1);
}

上述這段代碼的時間復雜度為O(NlogN)比第二種方法又提高了很多。

動態規劃

實際上這個問題還有另一種更妙的解決方法,我們令dp(i)表示以元素A[i]為結尾的最大子數組的和,那么根據這一定義則有:

860dadd6-b15c-11ec-aa7f-dac502259ad0.png

這是很顯然的,注意dp(i)的定義,是以元素A[i]為結尾的最大子數組的和,因此dp(i)的值要么就是A[i]連接上之前的一個子數組,那么不鏈接任何數組,那么最終的結果一定是以某個元素為結尾的子數組,因此我們從所有的dp(i)中取一個最大的就好了,依賴子問題解決當前問題的解就是所謂的動態規劃。

有了這些分析,代碼非常簡單:

intmaxSubArray(vector&nums){
intsize=nums.size();
vectordp(size,0);
intres=dp[0]=nums[0];
for(inti=1;ireturnres;
}

這段代碼簡單到讓人難以置信,只有8行代碼,你甚至可能會懷疑這段代碼的正確性,但它的確是沒有任何問題的,而且這段代碼的時間復雜度只有O(N),這段代碼既簡單運行速度又快,這大概就是算法的魅力吧。

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4968

    瀏覽量

    73969
  • 數組
    +關注

    關注

    1

    文章

    420

    瀏覽量

    27358

原文標題:動態規劃:8行代碼搞定最大子數組和問題

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數據結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    EN18031 認證全解析:三大子標準搞定歐盟網絡安全合規

    2026年歐盟網絡安全監管持續收緊,EN18031作為RED指令強制網絡安全標準,已成為無線設備出海歐盟的核心門檻。該認證由三大子標準構成,分別對應不同安全場景,精準匹配即可高效完成合規。本文全面
    的頭像 發表于 02-06 15:41 ?1893次閱讀
    EN18031 認證全解析:三<b class='flag-5'>大子</b>標準<b class='flag-5'>搞定</b>歐盟網絡安全合規

    不懂編程,怎么搞定電子儀表上位機軟件?零代碼搞定上位機軟件開發

    “不懂編程,怎么搞定電子儀表上位機軟件?”這是很多電子儀表用戶的共同困惑。傳統上位機開發被“專業編程”門檻牢牢限制,即便你對測試需求了如指掌(比如知道要采集哪些儀表數據、怎么分析波形、怎么生成
    的頭像 發表于 01-27 17:19 ?563次閱讀
    不懂編程,怎么<b class='flag-5'>搞定</b>電子儀表上位機軟件?零<b class='flag-5'>代碼</b><b class='flag-5'>搞定</b>上位機軟件開發

    RT-Thread Vector軟件包:嵌入式開發的動態數組容器 | 技術集結

    RT-Thread Vector軟件包:嵌入式開發的動態數組容器 | 技術集結
    的頭像 發表于 01-25 09:33 ?5379次閱讀
    RT-Thread Vector軟件包:嵌入式開發的<b class='flag-5'>動態</b><b class='flag-5'>數組</b>容器 | 技術集結

    keil中c語言的動態分配內存

    )包含柔性數組成員的結構體要用malloc函數進行動態內存分配,并且分配的內存應該大于該結構體的大小以適應柔性數組的預期大小。看下面的代碼: 其實上面的
    發表于 01-21 06:04

    深開鴻開源鴻蒙社區主干代碼貢獻量破650萬

    歷經五年發展,開源鴻蒙已從技術萌芽成長為萬物智聯時代的核心數字底座。秉持開源、共建、共享、共榮的理念,其生態規模持續擴張,累計匯聚超10000名貢獻者、510多家合作伙伴,沉淀1.3億代碼
    的頭像 發表于 01-07 10:22 ?510次閱讀

    二維數組介紹

    大家不要認為二維數組在內存中就是按、列這樣二維存儲的,實際上,不管二維、三維數組… 都是編譯器的語法糖。 存儲上和一維數組沒有本質區別,舉個例子: int array[3][3
    發表于 11-25 07:42

    基于感知引導的多步驟精細操作任務與運動規劃

    傳統的任務與運動規劃(TAMP)系統在機器人操作應用中通常依賴靜態模型運行,因此在面對新環境時往往表現不佳。將感知與操作相融合,是應對這一挑戰的有效途徑,使機器人能夠在執行過程中實時更新規劃,從而適應動態變化的場景。
    的頭像 發表于 11-14 10:18 ?1457次閱讀
    基于感知引導的多步驟精細操作任務與運動<b class='flag-5'>規劃</b>

    基于SIMP與折衷規劃法的航空附件齒輪箱結構輕量化設計與動態特性提升

    航空發動機附件齒輪箱作為動力傳遞系統的關鍵部件,其箱體結構設計直接影響發動機的功率密度、可靠性及振動特性。針對傳統經驗設計方法難以滿足高剛度、輕量化及高動態性能要求的挑戰,本文提出了一種基于折衷規劃法的多目標拓撲優化方法。
    的頭像 發表于 11-07 15:21 ?744次閱讀
    基于SIMP與折衷<b class='flag-5'>規劃</b>法的航空附件齒輪箱結構輕量化設計與<b class='flag-5'>動態</b>特性提升

    商品價格動態調整接口技術詳解

    ? ?在電商或零售系統中,商品價格需根據市場動態(如供需變化、競爭環境)實時調整,以最大化利潤和競爭力。本文將從接口設計、核心算法、實現代碼到優化策略,逐步解析如何構建一個高效的“商品價格動態
    的頭像 發表于 10-13 15:49 ?404次閱讀
    商品價格<b class='flag-5'>動態</b>調整接口技術詳解

    虹科動態 | 2025年8月精彩回顧

    」...下面讓我們一起回顧8月的虹科動態吧,9月精彩活動預告也不容錯過!01虹科動態1品牌動態8月7日,香港工業總會在港舉辦第65屆周年大會
    的頭像 發表于 09-02 10:13 ?807次閱讀
    虹科<b class='flag-5'>動態</b> | 2025年<b class='flag-5'>8</b>月精彩回顧

    華礪智成立八周年

    以落地中國為起點,2017年8月,華礪智砥礪八載春秋,從幾行通信代碼到覆蓋三大洲的智慧路網,用2920個晝夜完成了一場關于堅持的敘事,淬煉出堅固、立體、創新的多面形態。
    的頭像 發表于 08-20 14:51 ?854次閱讀

    AGV小車中的動態路徑規劃算法揭秘

    并非一成不變時,動態路徑規劃能力就顯得至關重要。本文將深入探討幾種主流的動態路徑規劃算法(如A、Dijkstra、RRT等),并解析它們如何在AGV行業中大顯身手。 為何需要
    的頭像 發表于 06-17 15:54 ?1700次閱讀
    AGV小車中的<b class='flag-5'>動態</b>路徑<b class='flag-5'>規劃</b>算法揭秘

    二維數組指定條件刪除指定,請教

    數組1的第一列進行條件判斷,如果小于20,刪除所在行,最終需要得到數組2
    發表于 05-13 08:11

    業精于視,成于旗—視旗科技CEO曾帥先生專訪

    企業家,用二十年生動詮釋“學一愛一干一”的強大精神力量可以實現人生“逆襲”。相信才會看見,信仰力量和赤子情懷驅動他在上海9年、深圳8年奮發圖強;看見會有未來,
    的頭像 發表于 04-25 17:19 ?727次閱讀
    業精于視,<b class='flag-5'>行</b>成于旗—視旗科技CEO曾帥先生專訪

    關于stm32,u8g2菜單之間切換(三)用u8g2寫一個菜單無限左右循環

    讓菜單循環播放只要用到的函數 void rotateRight (uint8_t *arr[], int n);讓數組右移 void rotateLeft ( uint8_t *arr[], int
    的頭像 發表于 03-11 09:10 ?1375次閱讀