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

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

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

最大子序和,貪心解法

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:代碼隨想錄 ? 作者:代碼隨想錄 ? 2022-05-10 10:37 ? 次閱讀

53. 最大子序和

力扣題目鏈接:https://leetcode-cn.com/problems/maximum-subarray

給定一個整數(shù)數(shù)組 nums ,找到一個具有最大和的連續(xù)子數(shù)組(子數(shù)組最少包含一個元素),返回其最大和。

示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4] 輸出: 6 解釋:連續(xù)子數(shù)組[4,-1,2,1] 的和最大,為 6。

暴力解法

暴力解法的思路,第一層for 就是設(shè)置起始位置,第二層for循環(huán)遍歷數(shù)組尋找最大值

時間復(fù)雜度:O(n^2) 空間復(fù)雜度:O(1)

classSolution{
public:
intmaxSubArray(vector<int>&nums){
intresult=INT32_MIN;
intcount=0;
for(inti=0;i//設(shè)置起始位置
count=0;
for(intj=i;j//每次從起始位置i開始遍歷尋找最大值
count+=nums[j];
result=count>result?count:result;
}
}
returnresult;
}
};

以上暴力的解法C++勉強可以過,其他語言就不確定了。

貪心解法

貪心貪的是哪里呢?

如果 -2 1 在一起,計算起點的時候,一定是從1開始計算,因為負數(shù)只會拉低總和,這就是貪心貪的地方!

局部最優(yōu):當前“連續(xù)和”為負數(shù)的時候立刻放棄,從下一個元素重新計算“連續(xù)和”,因為負數(shù)加上下一個元素 “連續(xù)和”只會越來越小。

全局最優(yōu):選取最大“連續(xù)和”

局部最優(yōu)的情況下,并記錄最大的“連續(xù)和”,可以推出全局最優(yōu)。

從代碼角度上來講:遍歷nums,從頭開始用count累積,如果count一旦加上nums[i]變?yōu)樨摂?shù),那么就應(yīng)該從nums[i+1]開始從0累積count了,因為已經(jīng)變?yōu)樨摂?shù)的count,只會拖累總和。

這相當于是暴力解法中的不斷調(diào)整最大子序和區(qū)間的起始位置。

那有同學(xué)問了,區(qū)間終止位置不用調(diào)整么?如何才能得到最大“連續(xù)和”呢?

區(qū)間的終止位置,其實就是如果count取到最大值了,及時記錄下來了。例如如下代碼:

if(count>result)result=count;

這樣相當于是用result記錄最大子序和區(qū)間和(變相的算是調(diào)整了終止位置)。

如動畫所示:

88d26216-d009-11ec-bce3-dac502259ad0.gif53.最大子序和

紅色的起始位置就是貪心每次取count為正數(shù)的時候,開始一個區(qū)間的統(tǒng)計。

那么不難寫出如下C++代碼(關(guān)鍵地方已經(jīng)注釋)

classSolution{
public:
intmaxSubArray(vector<int>&nums){
intresult=INT32_MIN;
intcount=0;
for(inti=0;iif(count>result){//取區(qū)間累計的最大值(相當于不斷確定最大子序終止位置)
result=count;
}
if(count<=?0)count=0;//相當于重置最大子序起始位置,因為遇到負數(shù)一定是拉低總和
}
returnresult;
}
};

時間復(fù)雜度:O(n) 空間復(fù)雜度:O(1)

當然題目沒有說如果數(shù)組為空,應(yīng)該返回什么,所以數(shù)組為空的話返回啥都可以了。

不少同學(xué)認為 如果輸入用例都是-1,或者 都是負數(shù),這個貪心算法跑出來的結(jié)果是0, 這是又一次證明腦洞模擬不靠譜的經(jīng)典案例,建議大家把代碼運行一下試一試,就知道了,也會理解 為什么 result 要初始化為最小負數(shù)了。

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

當然本題還可以用動態(tài)規(guī)劃來做,當前「代碼隨想錄」主要講解貪心系列,后續(xù)到動態(tài)規(guī)劃系列的時候會詳細講解本題的dp方法。

那么先給出我的dp代碼如下,有時間的錄友可以提前做一做:

classSolution{
public:
intmaxSubArray(vector<int>&nums){
if(nums.size()==0)return0;
vector<int>dp(nums.size(),0);//dp[i]表示包括i之前的最大連續(xù)子序列和
dp[0]=nums[0];
intresult=dp[0];
for(inti=1;i1]+nums[i],nums[i]);//狀態(tài)轉(zhuǎn)移公式
if(dp[i]>result)result=dp[i];//result保存dp[i]的最大值
}
returnresult;
}
};

時間復(fù)雜度:O(n) 空間復(fù)雜度:O(n)

總結(jié)

本題的貪心思路其實并不好想,這也進一步驗證了,別看貪心理論很直白,有時候看似是常識,但貪心的題目一點都不簡單!

后續(xù)將介紹的貪心題目都挺難的,哈哈,所以貪心很有意思,別小看貪心!

其他語言版本

Java

classSolution{
publicintmaxSubArray(int[]nums){
if(nums.length==1){
returnnums[0];
}
intsum=Integer.MIN_VALUE;
intcount=0;
for(inti=0;i//取區(qū)間累計的最大值(相當于不斷確定最大子序終止位置)
if(count<=?0){
count=0;//相當于重置最大子序起始位置,因為遇到負數(shù)一定是拉低總和
}
}
returnsum;
}
}
//DP方法
classSolution{
publicintmaxSubArray(int[]nums){
intans=Integer.MIN_VALUE;
int[]dp=newint[nums.length];
dp[0]=nums[0];
ans=dp[0];

for(inti=1;i1]+nums[i],nums[i]);
ans=Math.max(dp[i],ans);
}

returnans;
}
}

Python

classSolution:
defmaxSubArray(self,nums:List[int])->int:
result=-float('inf')
count=0
foriinrange(len(nums)):
count+=nums[i]
ifcount>result:
result=count
ifcount<=?0:
count=0
returnresult

Go

funcmaxSubArray(nums[]int)int{
maxSum:=nums[0]
fori:=1;ilen(nums);i++{
ifnums[i]+nums[i-1]>nums[i]{
nums[i]+=nums[i-1]
}
ifnums[i]>maxSum{
maxSum=nums[i]
}
}
returnmaxSum
}

--- EOF ---

審核編輯 :李倩


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

    關(guān)注

    1

    文章

    202

    瀏覽量

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

    關(guān)注

    1

    文章

    417

    瀏覽量

    25978

原文標題:最大子序和,又貪心又DP

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

收藏 人收藏

    評論

    相關(guān)推薦

    光纖的色是怎么排列的

    光纖的色排列通常遵循特定的標準,主要有兩種色排列方式,即BELLCORE的國標纖芯順序和國標全色譜。 BELLCORE的國標纖芯順序 顏色排列:藍、橙(桔)、綠、棕、灰、白、紅、黑、黃、紫、粉紅
    的頭像 發(fā)表于 01-06 17:53 ?67次閱讀

    ?核對電纜相的小技巧

    核對電纜相的技巧要訣核對相很重要,相不對事故到;一般沒有相表,蓄電池燈用靠技巧;一側(cè)相已明了,把它接地電阻小,一根燈線向地跑,還有
    的頭像 發(fā)表于 08-08 16:08 ?596次閱讀
    ?核對電纜相<b class='flag-5'>序</b>的小技巧

    斷相保護的原理、應(yīng)用和接線方法

    斷相保護是一種電氣保護措施,用于防止電動機因相錯誤或斷相故障而損壞。在工業(yè)自動化和電氣工程中,相斷相保護是非常重要的。 相斷相保護的原理 相
    的頭像 發(fā)表于 08-02 14:38 ?1897次閱讀

    繼電器的接線方法及工作原理

    引言 相繼電器是一種用于檢測電源相的電氣設(shè)備,其主要作用是確保電動機或其他電氣設(shè)備在正確的相下工作。在工業(yè)自動化、電力系統(tǒng)等領(lǐng)域,相繼電器的應(yīng)用非常廣泛。 相
    的頭像 發(fā)表于 08-02 14:30 ?1252次閱讀

    保護器報警怎么解決

    保護器是一種用于檢測和保護電動機相錯誤的裝置,當電動機的相錯誤時,相保護器會發(fā)出報警信號,以避免電動機因相錯誤而損壞或發(fā)生故障。
    的頭像 發(fā)表于 08-02 14:20 ?3937次閱讀

    保護器如何知道正確相

    保護器是一種用于保護電氣設(shè)備免受相錯誤影響的裝置。在電力系統(tǒng)中,相是指三相交流電的相位關(guān)系。正確的相可以確保電氣設(shè)備正常運行,而錯誤的相
    的頭像 發(fā)表于 08-02 14:13 ?1370次閱讀

    保護器怎么判斷好壞

    保護器是一種用于檢測和保護電力系統(tǒng)中相錯誤的裝置。在電力系統(tǒng)中,相錯誤可能會導(dǎo)致設(shè)備損壞、供電中斷等問題,因此相保護器在電力系統(tǒng)中具有重要的作用。 一、相
    的頭像 發(fā)表于 08-02 14:11 ?1624次閱讀

    怎么判斷相繼電器壞了

    繼電器是一種用于檢測和保護電力系統(tǒng)中相故障的設(shè)備。它能夠檢測到電力系統(tǒng)中的相錯誤,并在檢測到錯誤時發(fā)出信號,從而保護電力系統(tǒng)的正常運行。然而,相繼電器在使用過程中可能會出現(xiàn)故
    的頭像 發(fā)表于 08-02 11:21 ?1704次閱讀

    互感器型號及參數(shù)詳解

    互感器是一種用于測量和保護電力系統(tǒng)中零電流的設(shè)備。在電力系統(tǒng)中,零電流是指三相電流不平衡時產(chǎn)生的電流,它可能導(dǎo)致設(shè)備損壞和電力系統(tǒng)的不穩(wěn)定。因此,零互感器在電力系統(tǒng)中具有重要
    的頭像 發(fā)表于 07-25 15:59 ?1573次閱讀

    、負和零的產(chǎn)生原因

    、負和零是電力系統(tǒng)中常用的三個概念,它們分別表示三相交流電的相關(guān)系。在電力系統(tǒng)中,三相交流電的相關(guān)系對于電力系統(tǒng)的穩(wěn)定運行和設(shè)備
    的頭像 發(fā)表于 07-15 10:51 ?5354次閱讀

    分量各有什么特點

    、負和零分量是電力系統(tǒng)中分析不對稱故障的重要概念。它們分別代表了三相交流系統(tǒng)中的三種不同電流分布狀態(tài)。 正分量 正分量是指三相電
    的頭像 發(fā)表于 07-15 10:49 ?2242次閱讀

    繼電器簡介 相繼電器的應(yīng)用原理

    在許多三相交流電應(yīng)用的場合,相的正確有時是一項必須的條件,錯誤的相或缺相有可能導(dǎo)致設(shè)備工作不正常甚至損壞。
    的頭像 發(fā)表于 02-23 16:07 ?2.6w次閱讀
    相<b class='flag-5'>序</b>繼電器簡介 相<b class='flag-5'>序</b>繼電器的應(yīng)用原理

    為什么輸電線路的正阻抗比零阻抗小呢?

    為什么輸電線路的正阻抗比零阻抗小呢? 輸電線路的正阻抗比零阻抗小是由于以下幾個原因: 首先,輸電線路的正阻抗在設(shè)計和施工過程中通常
    的頭像 發(fā)表于 02-18 11:41 ?3051次閱讀

    單相接地時正電流與負電流、零電流相等嗎?

    單相接地時正電流與負電流、零電流相等嗎? 在單相接地系統(tǒng)中,正電流、負電流和零電流是
    的頭像 發(fā)表于 02-04 09:56 ?4119次閱讀

    什么是正電流?什么是負電流?什么是零電流?

    什么是正電流?什么是負電流?什么是零電流? 正電流:正電流是指在三相對稱電壓系統(tǒng)中,三相電流的相位角相同,大小相等,且按照a-b-
    的頭像 發(fā)表于 02-04 09:43 ?1.5w次閱讀