Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.
More practice:
If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
很自然的可以想到方法,暴力枚举,复杂度O(n^3)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class Solution {
    public int maxSubArray(int[] nums) {
        int ans=Integer.MIN_VALUE;
        int len=nums.length;
        for(int i=0;i<len;i++)
        {
            for(int j=i;j<len;j++)
            {
                int sum=0;
                for(int k=i;k<=j;k++)
                {
                    sum+=nums[k];
                    if(sum>ans)
                    {
                        ans=sum;
                    }
                }
            }
        }
        return ans;
    }
}
如何对上述算法进行改进呢?这就要看哪儿重复计算了
我们发现在计算sum的时候,没个区间都是单独计算一遍,这里重复了,所以改进如下,复杂度O(n^2)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class Solution {
    public int maxSubArray(int[] nums) {
        int ans=Integer.MIN_VALUE;
        int len=nums.length;
        for(int i=0;i<len;i++)
        {
            int sum=0;
            for(int j=i;j<len;j++)
            {
                sum+=nums[j];
                if(sum>ans)
                {
                    ans=sum;
                }
            }
        }
        return ans;
    }
}
还可以改进,用贪心的思想
每计算一个sum,比较是否比ans大,相当于记录了最大的sum。
如果sum是正数,如果继续加正数,sum肯定在增长
如果加了一个负数,其实无所谓,因为之前比较大的sum已经被记录了。
如果sum变成了一个负数,则重置sum=0,因为加个负数计算,肯定不会是最大的序列1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class Solution {
    public int maxSubArray(int[] nums) {
        int ans=Integer.MIN_VALUE;
        int sum=0;
        for(int i=0;i<nums.length;i++)
        {
            sum+=nums[i];
            if(sum>ans)
                ans=sum;
            if(sum<0)
                sum=0;
        }
        return ans;
    }
}