53 Maximum Subarray


title: Maximum Subarray
tags:
- maximum-subarray
- No.53
- simple
- divide-conquer
- mathematical-analysis


Problem

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

Corner Cases

  • empty array
  • all negative
  • all positive

Solutions

Divide and Conquer

For input array nums[], we can compute the sum array sums[] s.t.

sums[0] = 0;
sums[1] = 0 + nums[0];
sums[2] = 0 + nums[0] + nums[1];
sums[3] = 0 + nums[0] + nums[1] + nums[2];

and

nums[0] = sums[1] - sums[0];
nums[1] = sums[2] - sums[1];
nums[2] = sums[3] - sums[2];

Then any sum of continuous elements nums[i] + ... + nums[j] can be represented by sums[j+1] - sums[i]. Then, we can do divide and conquer more quickly.

Note that we must make sure that i <= j.

For any range [i : j] for sums, we divide it into two halves: [i : k] and [k+1 : j]. Then we have:

divideConquer(i, j) = max{ 
    divideConquer(i, k),
    divideConquer(k+1, j),
    max{sums[jj] - sums[ii]} // ii \in [i : j] && jj \in [k+1 : j]
}

It's obvious that:

max{sums[jj] - sums[ii]} = max{sums[k+1 : j]} - min{sums[i : j]}

This conclusion can be computed within O(n) time. Thus we have T(n) = 2 \times T(\frac{n}{2}) + O(n). The running is T(n) = O(n \lg(n)):

class Solution {
    private int[] sums;

    public int maxSubArray(int[] nums) {
        if (nums.length == 0) {return -2147483648;}

        sums = new int[1 + nums.length];
        for (int i=0, s=0; i<nums.length; i++) {
            s         = s + nums[i];
            sums[1+i] = s;
        }

        return divideConquer(0, sums.length-1);
    }

    public int divideConquer(int i, int j) {
        if ((i==j) || (i==0 && j==1)) {
            return sums[j]-sums[j-1];
        }

        int k = (i + j)/2;
        int a = divideConquer(i, k);
        int b = divideConquer(k+1, j);

        int cmax = -2147483648;
        int cmin = 2147483647;
        for (int jj=k+1; jj<=j; jj++) {
            cmax = (sums[jj] < cmax) ? cmax : sums[jj];
        }
        for (int ii=i; ii<=k; ii++) {
            cmin = (cmin < sums[ii]) ? cmin : sums[ii];
        }
        int c = cmax - cmin;

        return (((a > b) ? a : b) > c) ? ((a > b) ? a : b) : c;
    }
}

Zero Points

For continuous variable t and continous integralable function f(t) and the definite integral \int_{y}^{x} f(t)dt = F(x) - F(y), we have:

\frac{\partial F(x) - F(y)}{\partial x} = \frac{dF}{dx}(x) = f(x) = 0

\frac{\partial F(x) - F(y)}{\partial y} = \frac{dF}{dy}(y) = f(y) = 0

This is the relationship of the Force and Work. That is to say: we sometimes do positive work, sometimes do negative work, and want to figure out the largest Potential difference. Since the extremums occur at zeros of derivative function, we check nums for changing signs.

[-2, 1,-3, 4,-1, 2, 1,-5, 4]
 **0** **2** **4** **6**
    **1** **3** **5** **7**

We have 8 pairs of zeros to check here above. This method is bad when zeros are close to each other, but relative good when they are sparse.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,854評論 0 10
  • 課程筆記 分身術(shù)學(xué)習(xí)的三個層次:以語言為先,以情緒為里,以信念為根 信念是本質(zhì)性的沖突,是情緒產(chǎn)生的根源,是我們堅...
    云陽S閱讀 485評論 0 0
  • 1、你的一生,我只借一程,這一程,是余生。 2、世界上最痛苦的事,莫過于眼睜睜看著你愛的人愛上了別人。因為你知道,...
    華水亦閱讀 623評論 0 1
  • 多年前,一個少年懷揣3000元開始了任性隨意的旅行。從青海到甘肅,從甘肅到西藏,最自由的行程也莫不如是。西藏的沙土...
    韻小喵閱讀 527評論 4 1
  • 摘抄: 1所謂需要專注的時間之外的時間,就像跳高前的助跑。想跳得更高,如何做好助跑很重要。同樣的道理,要專注做某事...
    答案就在你心里28閱讀 260評論 0 0

友情鏈接更多精彩內(nèi)容