色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

動態(tài)規(guī)劃:8行代碼搞定最大子數(shù)組和問題

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:碼農(nóng)的荒島求生 ? 作者:碼農(nóng)的荒島求生 ? 2022-04-01 10:24 ? 次閱讀

鐵子們,我是小風(fēng)哥,你也可以叫我島主

今天給大家?guī)硪坏罉O其經(jīng)典的題目,叫做最大和子數(shù)組,給定一個數(shù)組,找到其中的一個連續(xù)子數(shù)組,其和最大。

示例:

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

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

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

暴力求解

這種解法最簡單,我們把所有子數(shù)組找出來,然后依次計(jì)算其和,找出一個最大的出來,比如給定數(shù)組[1,2,3],那么我們能找出子數(shù)組:[1],[2],[3],[1,2],[2,3],[1,2,3],很顯然這里和最大的子數(shù)組為[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;
}

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

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

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

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

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

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

還有沒有進(jìn)一步提高的空間呢?

答案是肯定的。

分而治之

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

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

然后呢?

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

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

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

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

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

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

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

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

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

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

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

根據(jù)上面的分析就可以寫代碼了:

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);
}

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

動態(tài)規(guī)劃

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

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

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

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

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

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

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4799

    瀏覽量

    68728
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    417

    瀏覽量

    25975

原文標(biāo)題:動態(tài)規(guī)劃:8行代碼搞定最大子數(shù)組和問題

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Labivew 實(shí)現(xiàn)鼠標(biāo)在數(shù)組中選中元素時,精準(zhǔn)的顯示所在位置的、列值方法

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

    數(shù)組的下標(biāo)為什么可以是負(fù)數(shù)

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

    數(shù)組名之間可以直接賦值嗎

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

    指針數(shù)組和二維數(shù)組有沒有區(qū)別

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

    C語言數(shù)組應(yīng)用計(jì)算機(jī)導(dǎo)論A第6講:數(shù)組

    C語言數(shù)組應(yīng)用計(jì)算機(jī)導(dǎo)論A第6講:數(shù)組
    發(fā)表于 11-20 15:33 ?0次下載

    labview按讀取二維數(shù)組之后再按讀取順序重新組成二維數(shù)組如何實(shí)現(xiàn)?

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

    labview字符串數(shù)組轉(zhuǎn)化為數(shù)值數(shù)組

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

    面試???1:函數(shù)指針與指針函數(shù)、數(shù)組指針與指針數(shù)組

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

    如何在代碼動態(tài)修改手指電容?

    如何在代碼動態(tài)修改手指電容
    發(fā)表于 05-22 07:11

    stm32通過串口發(fā)送字符串存在數(shù)組里面遇到的疑問求解

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

    深入探索KUKA KRL中的數(shù)組應(yīng)用

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

    PSoC4訪問數(shù)組時產(chǎn)生無限循環(huán)的原因?

    我寫了幾乎 10000 代碼,一切都工作正常,但最近我創(chuàng)建了一個 16 EVAL_2KW_48V_CHAR_P7的新數(shù)組,如果我訪問它,程序就會掛起...... 調(diào)試器顯示程序跳轉(zhuǎn)到了不應(yīng)該
    發(fā)表于 03-05 06:24

    數(shù)組和鏈表在內(nèi)存中的區(qū)別 數(shù)組和鏈表的優(yōu)缺點(diǎn)

    數(shù)組和鏈表在內(nèi)存中的區(qū)別 數(shù)組和鏈表的優(yōu)缺點(diǎn)? 數(shù)組和鏈表是常見的數(shù)據(jù)結(jié)構(gòu),用于組織和存儲數(shù)據(jù)。它們在內(nèi)存中的存儲方式以及優(yōu)缺點(diǎn)方面存在一些顯著的差異。本文將詳細(xì)探討這些差異以及它們的優(yōu)缺點(diǎn)。 1.
    的頭像 發(fā)表于 02-21 11:30 ?1060次閱讀

    數(shù)組和鏈表有何區(qū)別

    數(shù)組和鏈表的區(qū)別,這個問題,不僅面試中經(jīng)常遇到,考研的同學(xué)也得掌握才。
    的頭像 發(fā)表于 02-19 15:33 ?528次閱讀
    <b class='flag-5'>數(shù)組</b>和鏈表有何區(qū)別

    PHP中數(shù)組的使用方法!

    PHP中數(shù)組的使用方法! PHP是一種廣泛使用的網(wǎng)絡(luò)編程語言,它的數(shù)組功能非常強(qiáng)大且靈活。數(shù)組是一種數(shù)據(jù)結(jié)構(gòu),它允許我們在單個變量中存儲多個值。 在本篇文章中,我將詳細(xì)解釋PHP數(shù)組
    的頭像 發(fā)表于 01-12 15:11 ?566次閱讀
    主站蜘蛛池模板: 中文字幕AV在线一二三区| 女配穿书病娇被强啪h| 2019香蕉在线观看直播视频 | 扒开小处30p| 野花香在线观看免费观看大全动漫 | 久久免费资源福利资源站| 国产精品无码无卡毛片不卡视 | 我半夜摸妺妺的奶C了她软件| 免费人成在线观看网站视频| 国产三级在线观看视频| 嘟嘟嘟WWW在线观看视频高清| 99国产精品久久人妻无码| 野花日本免费完整版高清版动漫| 幸福草电视剧演员表介绍| 手机观看毛片| 性美国人xxxxx18| 亚洲精品第一综合99久久| 亚洲伦理精品久久| 一区在线观看在线| 综合久久伊人| 97在线播放| 趁老师睡着吃她的奶水| 国产3级在线观看| 国产强奷伦奷片| 久草在线新是免费视频| 久欠热视频精品首页| 嫩草影院在线观看精品视频| 全身无赤裸裸美女网站| 四虎影视国产精品亚洲精品| 亚洲 欧美 日韩 精品 自拍| 野花香在线观看免费观看大全动漫 | 歪歪漫画羞羞漫画国产| 亚洲精品第一国产综合| 尤物久久99国产综合精品| 97国产蝌蚪视频在线观看| swag合集120部| 国产AV亚洲国产AV麻豆| 好紧的小嫩嫩17p| 久久视频这里只精品99热在线观看| 男女牲交全过程免费播放| 日本三级按摩推拿按摩|