Leetcode - Maximum Subarray


My code:

public class Solution {
public int maxSubArray(int[] nums) {
if (nums == null || nums.length == 0)
return 0;
else if (nums.length == 1)
return nums[0];

    int maxSum = nums[0];
    int currSum = nums[0];
    for (int i = 1; i < nums.length; i++) {
        currSum = currSum >= 0 ? currSum + nums[i] : nums[i]; 
        maxSum = Integer.max(maxSum, currSum);  
    }
    return maxSum;
}

}


My test result:

![](http://upload-images.jianshu.io/upload_images/161212-fd9cf6a95e234da4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


這道題目不算很難,但我知道我一定會(huì)想復(fù)雜宏赘。所以在動(dòng)手痛苦得設(shè)置狀態(tài)機(jī)之前還是決定看下別人的思路吧哮针。否則又是亂寫,浪費(fèi)時(shí)間计福「抛鳎靠if語句做出答案沪袭。思維是垃圾的。
其實(shí)面對(duì)這種妒御,求 max of sub array 的題目解愤,我每次一看到題,都會(huì)一種誤解乎莉,需要求出這個(gè)最大值送讲,方法是奸笤,找出求得這個(gè)最大值的區(qū)域范圍。
其實(shí)完全不需要哼鬓。我們只需要求最大值监右。那么,最大值可以不斷刷新异希,當(dāng)新的更大的值出現(xiàn)的時(shí)候健盒,就將maxSum刷新。而不需要記錄這個(gè)刷新值的起點(diǎn)和尾點(diǎn)是哪里称簿。
于是只需要考慮一種情況扣癣。
當(dāng) currSum < 0 時(shí),此時(shí)后一個(gè)值加上 currSum 予跌,總sum都會(huì)變小搏色。
所以直接將 currSum = nums[i]
如果 nums[i] <= 0 善茎, 那么券册,也許,原 currSum 是要大于 此時(shí)的currSum的。
但那又如何呢垂涯?currSum保存的只是現(xiàn)在的和烁焙。而最大和,是保存在 maxSum里面的耕赘。
所以只需要比較下原maxSum 和 現(xiàn)currSum 大小即可骄蝇。取最大值。
如果 nums[i] > 0, 那么此刻操骡,因?yàn)?currSum <= 0 ,所以
currSum + nums[i] <= nums[i] 的九火。所以可以從nums[i] 重新開始,不需要加上之前的負(fù)數(shù)册招。
如果原currSum > 0 ,那就直接加上 nums[i], 不斷與maxSum比較岔激,不斷刷新maxSum即可。

**
總結(jié): Array是掰, DP虑鼎。 求 sub array 的最大和。記住键痛,只需要求出最大和炫彩,而不需要考慮任何有關(guān)該最大和起止點(diǎn)的問題。
** 

Anyway, Good luck, Richardo!



My code:

public class Solution {
public int maxSubArray(int[] nums) {
if (nums == null || nums.length == 0)
return 0;
int tracker = nums[0];
int max = nums[0];
for (int i = 1; i < nums.length; i++) {
tracker = Math.max(tracker + nums[i], nums[i]);
max = Math.max(max, tracker);
}
return max;
}
}


剛做完 maximum subarray product, 
http://www.reibang.com/p/e1456b90c819
所以這道題做起來比較快絮短。

差不多的思路江兢,用一個(gè)tracker去追蹤之前最大的和,必須與現(xiàn)在這個(gè)index相連丁频。然后杉允,再綜合找出最大值扔嵌。

Anyway, Good luck, Richardo!


一開始也是直接拿O(n) 方法做的,后來看到有 divide and conquer做法夺颤,就看了解釋痢缎,然后自己寫了一遍。

```java
public class Solution {
    public int maxSubArray(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        return helper(nums, 0, nums.length - 1);
    }
    
    private int helper(int[] nums, int left, int right) {
        if (left == right) {
            return nums[left];
        }
        int middle = left + (right - left) / 2;
        int leftMax = helper(nums, left, middle);
        int rightMax = helper(nums, middle + 1, right);
        int leftPart = Integer.MIN_VALUE;
        int temp = 0;
        for (int i = middle; i >= left; i--) {
            temp += nums[i];
            leftPart = Math.max(leftPart, temp);
        }
        int rightPart = Integer.MIN_VALUE;
        temp = 0;
        for (int i = middle + 1; i <= right; i++) {
            temp += nums[i];
            rightPart = Math.max(rightPart, temp);
        }
        
        int crossMax = leftPart + rightPart;
        return Math.max(crossMax, Math.max(leftMax, rightMax));
    }
}

參考:
https://discuss.leetcode.com/topic/49641/simple-divide-and-conquer-solution-java-answer-for-the-more-practice

只不過覺得好沒意思世澜。独旷。。太不自然的想法了寥裂,速度也很慢嵌洼。

Anyway, Good luck, Richardo!

如果問,找出這個(gè)sub array 的途徑:

My code:

public int[] maxSubArrayPath(int[] nums) {
    if (nums == null || nums.length == 0) {
        return null;
    }
    
    int max = nums[0];
    int sum = nums[0];
    int begin = 0;
    int end = 0;
    int currBegin = 0;
    int currEnd = 0;
    for (int i = 1; i < nums.length; i++) {
        if (sum + nums[i] >= nums[i]) {
            sum += nums[i];
            currEnd = i;
        }
        else {
            sum = nums[i];
            currBegin = i;
            currEnd = i;
        }
        if (max < sum) {
            begin = currBegin;
            end = currEnd;
            max = sum;
        }
    }
    return new int[]{begin, end};
}

如果問封恰,找出不大于 k 的最大sub array 和
My code:

public int maxSubArrayK(int[] nums, int k) {
        int n = nums.length;
        int[] sums = new int[n];
        int temp = 0;
        TreeSet<Integer> set = new TreeSet<Integer>();
        for (int i = 0; i < nums.length; i++) {
            temp += nums[i];
            sums[i] = temp;
            set.add(temp);
        }
        set.add(0);
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            Integer num = set.ceiling(nums[i] - k);
            if (num != null) {
                max = Math.max(max, nums[i] - num);
            }
        }
        
        return max == Integer.MIN_VALUE ? -1 : max;
    }

Anyway, Good luck, Richardo! -- 09/24/2016

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末麻养,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子诺舔,更是在濱河造成了極大的恐慌鳖昌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件低飒,死亡現(xiàn)場(chǎng)離奇詭異许昨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)褥赊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門糕档,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拌喉,你說我怎么就攤上這事速那。” “怎么了尿背?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵端仰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我残家,道長(zhǎng)榆俺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任坞淮,我火速辦了婚禮茴晋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘回窘。我一直安慰自己诺擅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布啡直。 她就那樣靜靜地躺著烁涌,像睡著了一般苍碟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撮执,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天微峰,我揣著相機(jī)與錄音,去河邊找鬼抒钱。 笑死蜓肆,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谋币。 我是一名探鬼主播仗扬,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蕾额!你這毒婦竟也來了早芭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤诅蝶,失蹤者是張志新(化名)和其女友劉穎退个,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秤涩,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帜乞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了筐眷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡习柠,死狀恐怖匀谣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情资溃,我是刑警寧澤武翎,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站溶锭,受9級(jí)特大地震影響宝恶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜趴捅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一垫毙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拱绑,春花似錦综芥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屠阻。三九已至,卻和暖如春额各,著一層夾襖步出監(jiān)牢的瞬間国觉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工虾啦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛉加,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓缸逃,卻偏偏與公主長(zhǎng)得像针饥,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子需频,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

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