【leetcode】Maximum Subarray

class Solution {
public:
    int maxSubArray(int A[], int n) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        if(n==0)
            return 0;
        int nStart=A[n-1];
        int nAll=A[n-1];
        for(int i=n-2;i>=0;i--)//O(n)
        {
            nStart=(nStart+A[i])>A[i]?(nStart+A[i]):A[i];
            nAll=nAll>nStart?nAll:nStart;
        }
        return nAll;
    }
};

 (2) Divide and Conquer

二分法:将数组分成左右两部分,递归求两部分最大连续子数组,由于最大连续子数组可能横跨左右,故需对这种情况进行处理

假设数组A[left, right]存在最大值区间[i, j](i>=left & j<=right),以mid = (left + right)/2 分界,无非以下三种情况:

subarray A[i,..j] is
(1) Entirely in A[low,mid-1]
(2) Entirely in A[mid+1,high]
(3) Across mid
对于(1) and (2),直接递归求解即可,对于(3),则需要以min为中心,向左及向右扫描求最大值,意味着在A[left, Mid]区间中找出A[i..mid], 而在A[mid+1, right]中找出A[mid+1..j],两者加和即为(3)的解。

比较三种情况下得到的子数组和,取其中最大值

复制代码
 1 public int maxSubArray(int[] A) {
 2         // Start typing your Java solution below
 3         // DO NOT write main() function
 4         int max = Integer.MIN_VALUE;
 5         return maxArray(A, 0, A.length - 1, max);
 6     }
 7     
 8     int maxArray(int[] A, int left, int right, int max){
 9         if(left > right){
10             return Integer.MIN_VALUE;
11         }
12         
13         int mid = (left + right) / 2;
14         int leftMax = maxArray(A, left, mid - 1, max);
15         int rightMax = maxArray(A, mid + 1, right, max);
16         
17         max = Math.max(max, leftMax);
18         max = Math.max(max, rightMax);
19         
20         int sum = 0, mlmax = 0;
21         for(int i = mid - 1; i >= left; i--){
22             sum += A[i];
23             if(sum > mlmax){
24                 mlmax = sum;
25             }
26         }
27         sum = 0; int mrmax = 0;
28         for(int i = mid + 1; i <= right; i++){
29             sum += A[i];
30             if(sum > mrmax){
31                 mrmax = sum;
32             }
33         }
34         max = Math.max(max, A[mid] + mlmax + mrmax);
35         return max;
36     }
复制代码

时间复杂度: T(N) = 2*T(N/2) + O(N) 由主定理得 O(NlogN)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值