LeetCode——Maximum Subarray

Description:

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.

click to show more practice.

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.

看见这题的第一想法就是决不能用暴力穷举。

然后应该会想到简单的dp。思路就是每次都选择最大的sum(这不是贪心?)。时间复杂度是O(n),空间复杂度是O(1);

public class Solution {
    public int maxSubArray(int[] nums) {
        
        int max = nums[0];
        int sum = 0;
        for(int i=0; i<nums.length; i++) {
            sum += nums[i];
            if(max < sum) max = sum;
            if(sum < 0) sum = 0;
        }
        
        return max;
        
    }
}

题目最后还有一个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(nlogn),空间复杂度是O(logn);

public class Solution {
    
//分治
public int divide(int[] nums, int m, int n) { if(m == n) { return nums[m]; } int mid = m + (n-m)/2; //防止整数溢出 int home = divide(nums, m, mid); int end = divide(nums, mid+1, n); int sum = merge(nums, m, n, mid); return max(sum, max(home, end)); }
//合并
public int merge(int[] nums, int m, int n, int mid) { int leftMax = nums[mid]; int sum = 0; for(int i=mid; i>=m; i--) { sum += nums[i]; if(leftMax < sum) { leftMax = sum; } } sum = 0; int rightMax = nums[mid+1]; for(int i=mid+1; i<=n; i++) { sum += nums[i]; if(rightMax < sum) { rightMax = sum; } } sum = leftMax + rightMax; return sum; } public int max(int a, int b) { return a > b ? a : b; } public int maxSubArray(int[] nums) { if(nums.length <= 0) { return 0; } int res = divide(nums, 0, nums.length-1); return res; } }

分治、dp、贪心有时候傻傻分不清楚。

 

posted @ 2015-09-30 19:03  Pickle  阅读(234)  评论(0编辑  收藏  举报