在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

    文章

    4813

    瀏覽量

    68833
  • 數組
    +關注

    關注

    1

    文章

    417

    瀏覽量

    25990

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

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

收藏 人收藏

    評論

    相關推薦

    Labivew 實現鼠標在數組中選中元素時,精準的顯示所在位置的、列值方法

    在項目開發中,遇到一個布爾的二維數組輸入控件,選中數組元素并索引出行列的操作,試過其他大佬的方法,不是特別精準,,嘗試一下還可以,分享給需要的朋友 *附件:選中二維數組元素并索引所在的
    發表于 12-21 18:07

    數組的下標為什么可以是負數

    最近有同學發來這樣一段代碼,并提出一個問題,數組的下標為什么可以是負數? ? ? #include int main(){ const char *s = "helloworld"; const
    的頭像 發表于 12-20 11:18 ?135次閱讀

    數組名之間可以直接賦值嗎

    數組之間的賦值能不能直接使用等于號?比如這樣的代碼。 int main(){ int a[5] = {1, 2, 3, 4, 5}; int b[5] = {0}; b = a
    的頭像 發表于 11-26 11:23 ?189次閱讀

    指針數組和二維數組有沒有區別

    指針數組和二維數組有沒有區別?比如這樣的兩個代碼。 int main(){ char *s1[] = { "hello", "world", "total" }; char s2[][6
    的頭像 發表于 11-24 11:12 ?197次閱讀

    C語言數組應用計算機導論A第6講:數組

    C語言數組應用計算機導論A第6講:數組
    發表于 11-20 15:33 ?0次下載

    labview按讀取二維數組之后再按讀取順序重新組成二維數組如何實現?

    labview用了index Array按索引一行行讀取二維數組之后想再按讀取順序重新組成一個二維數組如何實現,即第一次讀取的作為第一,第二次讀取的作為第二
    發表于 10-25 21:06

    labview字符串數組轉化為數值數組

    在LabVIEW中,將字符串數組轉換為數值數組是一項常見的任務,尤其是在處理數據采集、信號處理或用戶輸入時。 1. 理解LabVIEW的數據類型 在開始之前,了解LabVIEW中的數據類型是非
    的頭像 發表于 09-04 17:47 ?2656次閱讀

    面試???1:函數指針與指針函數、數組指針與指針數組

    在嵌入式開發領域,函數指針、指針函數、數組指針和指針數組是一些非常重要但又容易混淆的概念。理解它們的特性和應用場景,對于提升嵌入式程序的效率和質量至關重要。一、指針函數與函數指針指針函數:定義:指針
    的頭像 發表于 08-10 08:11 ?953次閱讀
    面試???1:函數指針與指針函數、<b class='flag-5'>數組</b>指針與指針<b class='flag-5'>數組</b>

    如何在代碼動態修改手指電容?

    如何在代碼動態修改手指電容
    發表于 05-22 07:11

    stm32通過串口發送字符串存在數組里面遇到的疑問求解

    如題,想通過串口發送字符串存在數組里面,然后在串口助手上打印出來,一開始計數值沒有清零導致數據總是會被覆蓋,調試了好久終于搞定,但是我在仿真窗口觀察數組數據發現了問題,數據并沒有存放在數組
    發表于 05-14 08:15

    深入探索KUKA KRL中的數組應用

    如果 CHAR 類型數組的所有數組元素都擁有相同的字符串,則不必單獨初始化每個數組元素。忽略右側的數組下標。(對于一維數組下標,不寫下標。)
    的頭像 發表于 04-18 10:37 ?1303次閱讀
    深入探索KUKA KRL中的<b class='flag-5'>數組</b>應用

    PSoC4訪問數組時產生無限循環的原因?

    我寫了幾乎 10000 代碼,一切都工作正常,但最近我創建了一個 16 EVAL_2KW_48V_CHAR_P7的新數組,如果我訪問它,程序就會掛起...... 調試器顯示程序跳轉到了不應該
    發表于 03-05 06:24

    數組和鏈表在內存中的區別 數組和鏈表的優缺點

    數組和鏈表在內存中的區別 數組和鏈表的優缺點? 數組和鏈表是常見的數據結構,用于組織和存儲數據。它們在內存中的存儲方式以及優缺點方面存在一些顯著的差異。本文將詳細探討這些差異以及它們的優缺點。 1.
    的頭像 發表于 02-21 11:30 ?1088次閱讀

    數組和鏈表有何區別

    數組和鏈表的區別,這個問題,不僅面試中經常遇到,考研的同學也得掌握才。
    的頭像 發表于 02-19 15:33 ?547次閱讀
    <b class='flag-5'>數組</b>和鏈表有何區別

    鴻蒙二進制數組創建

    背景 c++層數據都是二進制,需要轉換成arrayBuffer透傳到ets層給業務使用,但是鴻蒙的使用下面兩個api創建出來的二進制數組數據都是錯誤的。 接口
    的頭像 發表于 01-31 15:24 ?1304次閱讀
    主站蜘蛛池模板: 亚洲色图综合| 亚洲综合激情网| a看片| 久久国内视频| 国产在线综合网| 成人激情在线| 欧美精品xx| 日本欧洲亚洲一区在线观看| 美女扒开尿口让男人捅| 伊人丁香婷婷综合一区二区| 五月婷婷丁香在线| 欧美污视频网站| 国产主播在线一区| 在线免费视频手机版| 人人干人人搞| 日xxxx| 国产亚洲欧美一区| 特级一级片| 免费拍拍视频| www.色com| 欧美成人三级网站| 最新sss华人| 美女扒开尿口给男人桶动态图 | 天天激情站| 久久福利精品| 亚洲视屏一区| 亚洲wuma| 另类激情网| 亚洲第一网站| 97久草| 99久久精品费精品国产一区二| 四虎成人免费网站在线| 黄色一级视频网| 特黄十八岁大片| 91大神精品长腿在线观看网站| 综合激情五月婷婷| 欧美日韩亚洲国产| 亚洲 欧美 日韩 丝袜 另类| 56pao强力打造| 亚洲综合情| 九九九精品视频免费|