一道題把我氣笑了:) 力扣.53 最大子數(shù)組和 leetcode maximum-subarray

數(shù)組系列

力扣數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組-00-概覽

力扣.53 最大子數(shù)組和 maximum-subarray

力扣.128 最長連續(xù)系列 longest-consecutive-sequence

力扣.1 兩數(shù)之和 N 種解法 two-sum

力扣.167 兩數(shù)之和 II two-sum-ii

力扣.170 兩數(shù)之和 III two-sum-iii

力扣.653 兩數(shù)之和 IV two-sum-IV

力扣.015 三數(shù)之和 IV three-sum

題目

給你一個(gè)整數(shù)數(shù)組 nums 挪凑,請你找出一個(gè)具有最大和的連續(xù)子數(shù)組(子數(shù)組最少包含一個(gè)元素)眨补,返回其最大和。

子數(shù)組是數(shù)組中的一個(gè)連續(xù)部分。

示例 1:

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

輸入:nums = [1]
輸出:1
示例 3:

輸入:nums = [5,4,-1,7,8]
輸出:23

提示:

1 <= nums.length <= 10^5
-104 <= nums[i] <= 10^4

進(jìn)階:如果你已經(jīng)實(shí)現(xiàn)復(fù)雜度為 O(n) 的解法,嘗試使用更為精妙的 分治法 求解贡必。

v1-前綴和 BF

思路

看到連續(xù)子數(shù)組和,比較自然的是想到用前綴和來加速子數(shù)組和的計(jì)算庸毫。

1)構(gòu)建好前綴和

2)窮舉所有可能的子數(shù)組和仔拟,找出最大值。

實(shí)現(xiàn)

class Solution {
    public int maxSubArray(int[] nums) {
        final int n = nums.length;

        int[] prefixSum = new int[n];
        prefixSum[0] = nums[0];
        for(int i = 1; i < n; i++) {
            prefixSum[i] = prefixSum[i-1] + nums[i];
        }

        // BF 匹配
        int maxSum = nums[0];
        for(int i = 0; i < n; i++) {
            // 后面的數(shù)組 》 前一個(gè)標(biāo)識
            for(int j = i; j < n; j++) {
                int sum = prefixSum[j] - prefixSum[i] + nums[i];

                // 更新最大值
                 maxSum = Math.max(maxSum, sum);
            }
        }
        return maxSum;
    }
}

效果

超出時(shí)間限制

204 / 210 個(gè)通過的測試用例

v2-如何改進(jìn)? 雙指針飒赃?

思路

我們之所以很慢利花,是因?yàn)樵谟?jì)算連續(xù)子數(shù)組和的時(shí)候,計(jì)算了各種場景载佳。但是這里要如何優(yōu)化呢炒事?

但是不對比所有的,如何找到最大的呢蔫慧?

最氣人的是題目中的那一句:如果你已經(jīng)實(shí)現(xiàn)復(fù)雜度為 O(n) 的解法挠乳,嘗試使用更為精妙的 分治法 求解。

左右兩邊的雙指針可行嗎姑躲?

感覺雙指針不可行 雙指針適合計(jì)算最大的長度睡扬,但是不太適合這種最大的和。

v3-貪心

思路1

看了一眼相似題目黍析,其中有一個(gè)是 【買賣股票的最佳時(shí)機(jī)】{簡單}

于是貪心的話卖怜,思路可以簡化為:

public int maxSubArray(int[] nums) {
    final int n = nums.length;
    // BF 匹配
    int maxSum = nums[0];
    for(int i = 1; i < n; i++) {
        // 加上當(dāng)前值變大?不加當(dāng)前值阐枣?
        // 變大
        int num = nums[i];
        // 無腦直接加
        if(num >= 0) {
            maxSum += num;
        } else {
            // 如果不是呢马靠?
            // 也不能貿(mào)然丟棄 因?yàn)檫B續(xù)起來,后來可能又大于0的蔼两?
            // 那么 怎么簡單的判斷這個(gè)事情呢甩鳄?
            
        }
    }
    return maxSum;
}

思路-打開評論區(qū)

首先看到一首打油詩 被逗笑了

打開我的題庫,調(diào)為簡單難度宪哩。

計(jì)算最大子數(shù)娩贷,直接給我難住。

報(bào)錯(cuò)鋪滿屏幕锁孟,凝望沒有思路彬祖。

縫縫補(bǔ)補(bǔ)做出,擊敗零個(gè)用戶品抽。

翻閱評論找補(bǔ)储笑,令我勃然大怒。

不禁心有一問圆恤,都是人突倍,憑什么我——這么廢物。

55555555

被打開的不單單是評論區(qū)的,當(dāng)然還有自己的思路羽历。

我們整體的方向沒錯(cuò)焊虏,但是這里需要一個(gè)技巧。

如下:

/**解題思路

用 temp 記錄局部最優(yōu)值秕磷,用 result 記錄全局最優(yōu)值诵闭。
每遍歷一個(gè)新元素時(shí),判斷(已遍歷的連續(xù)子數(shù)組的和)加上(當(dāng)前元素值)澎嚣,與(當(dāng)前元素值)對比誰更大疏尿。
(1)如果已遍歷的連續(xù)子數(shù)組的和 + 當(dāng)前元素值 >= 當(dāng)前元素值
說明(已遍歷的連續(xù)子數(shù)組的和)是大于等于0的,令 temp = 已遍歷的連續(xù)子數(shù)組的和 + 當(dāng)前元素值易桃。

(2)如果已遍歷的連續(xù)子數(shù)組的和 + 當(dāng)前元素值 < 當(dāng)前元素值
說明(已遍歷的連續(xù)子數(shù)組的和)是小于0的褥琐,加上這部分只會拖累當(dāng)前元素,故應(yīng)該直接拋棄掉這部分晤郑,令 * temp = 當(dāng)前元素值敌呈。

(3)對比 temp 和 result,如果 temp 更大贩汉,則更新到 result 中驱富。 
*/

代碼

class Solution {
    public int maxSubArray(int[] nums) {
        final int n = nums.length;

        // BF 匹配
        int maxSum = nums[0];
        int tempSum = nums[0];
        for(int i = 1; i < n; i++) {
            int num = nums[i];

            // 歷史數(shù)據(jù)大于等于0,則保留繼續(xù)累加
            if(tempSum >= 0) {
                tempSum += num;
            } else {
                // 歷史和小于 0匹舞,直接舍棄褐鸥。只保留今天
                tempSum = num;
            }

            maxSum = Math.max(maxSum, tempSum);
        }

        return maxSum;
    }
}

簡單的優(yōu)化,我們直接判斷是否大于等于0即可赐稽,減少一次累加計(jì)算叫榕。聊勝于無。

效果

1ms 100%

效果拔群

小結(jié)

那么這一題和股票有啥關(guān)系呢姊舵?

股票的買賣貪心其實(shí)要簡單一些晰绎,就是明天比今天高,直接無腦買賣括丁。而且不要求連續(xù)荞下。

這里要求連續(xù),就需要一個(gè)巧妙的構(gòu)思史飞,有時(shí)候不一定能很快想到尖昏。

比如我們可買賣股票無限次數(shù)上點(diǎn)難度,增加一個(gè)限制构资,買賣的天數(shù)必須是連續(xù)的天數(shù)抽诉,怎么解?

其實(shí)就是 {買+賣} 的和當(dāng)做一個(gè)數(shù)吐绵,然后就變成這一題了

v3-DP

思路

一個(gè)問題能不能被 DP 解決呢迹淌?

就看能不能拆分為遞推的子問題河绽。

那么,這個(gè)問題可以嗎?

遞推公式是什么唉窃?

也就是我們還是需要想到上面那個(gè)思路耙饰。

dp[i] = Math.max(0, dp[i-1]) + nums[i];

實(shí)現(xiàn)

class Solution {
    public int maxSubArray(int[] nums) {
        final int n = nums.length;

        int[] dp = new int[n];
        dp[0] = nums[0];
        int maxResult = nums[0];
        for(int i = 1; i < n; i++) {
            int num = nums[i];
            dp[i] = Math.max(0, dp[i-1]) + nums[i];
            maxResult = Math.max(dp[i], maxResult);
        }

        return maxResult;
    }
}

效果

2ms 36.91%

小結(jié)

DP 的優(yōu)點(diǎn)是使用范圍更加廣泛,這如果是一個(gè)系列的題目句携,不斷上難度榔幸,DP 也許可以成為一個(gè)模板。

但是如果是性能矮嫉,比不上上面的 greedy。

或者說上面的貪心牍疏,是對下面遞推數(shù)組的存儲空間優(yōu)化蠢笋。

差點(diǎn)掛在了第一個(gè)選擇的數(shù)組題目上....ORZ

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鳞陨,隨后出現(xiàn)的幾起案子昨寞,更是在濱河造成了極大的恐慌,老刑警劉巖厦滤,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件援岩,死亡現(xiàn)場離奇詭異,居然都是意外死亡掏导,警方通過查閱死者的電腦和手機(jī)享怀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趟咆,“玉大人添瓷,你說我怎么就攤上這事≈瞪矗” “怎么了鳞贷?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長虐唠。 經(jīng)常有香客問我搀愧,道長,這世上最難降的妖魔是什么疆偿? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任咱筛,我火速辦了婚禮,結(jié)果婚禮上翁脆,老公的妹妹穿的比我還像新娘眷蚓。我一直安慰自己,他們只是感情好反番,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布沙热。 她就那樣靜靜地躺著叉钥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篙贸。 梳的紋絲不亂的頭發(fā)上投队,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音爵川,去河邊找鬼敷鸦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寝贡,可吹牛的內(nèi)容都是我干的扒披。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼圃泡,長吁一口氣:“原來是場噩夢啊……” “哼碟案!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起颇蜡,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤价说,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后风秤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鳖目,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年缤弦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了领迈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甸鸟,死狀恐怖惦费,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抢韭,我是刑警寧澤薪贫,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站刻恭,受9級特大地震影響瞧省,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鳍贾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一鞍匾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧骑科,春花似錦橡淑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽置森。三九已至,卻和暖如春符糊,著一層夾襖步出監(jiān)牢的瞬間凫海,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工男娄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留行贪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓模闲,卻偏偏與公主長得像建瘫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子尸折,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容