分治法:找到数组的中心点mid,则最大连续元素和可能产生在:左侧子数组、右侧子数组、跨过中心点的数组。
代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        return find_recursive(nums,0,nums.size()-1);
    }
    int find_recursive(vector<int>& nums, int left,  int right)
    {
        if(left == right)
            return nums[left];
        else if(left > right)
            return 0;
        int mid = left + (right-left)/2;
        int max_left = find_recursive(nums, left, mid);
        int max_right = find_recursive(nums, mid+1, right);
        int max_mid = find_sub_array_with_middle(nums,left,mid,right);
        int ret = max(max_left, max_right);
        ret = max(ret,max_mid);
        return ret;
    }
    int find_sub_array_with_middle(vector<int>& nums, int left, int mid, int right)
    {
        int sum_left = INT_MIN;
        int sum = 0;
        for(int i = mid; i >= left; i--)
        {
            sum += nums[i];
            if(sum > sum_left)
                sum_left = sum;
        }
        sum = 0;
        int sum_right = INT_MIN;
        for(int i = mid+1 ; i <= right; i++)
        {
            sum += nums[i];
            if(sum > sum_right)
                sum_right = sum;
        }
        return sum_left+sum_right;
    }
};
运行时间:22ms,超过2.14%
动态规划:遍历数组,假设以i-1结尾的最长连续元素之和为local,则以i结尾的最长连续元素之和为max(nums[i],local+nums[i])。维护一个全局最大global,每一步进行更新。
代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int local = nums[0];
        int global = nums[0];
        for(int i = 1; i < nums.size(); i++)
        {
            local = max(nums[i], local+nums[i]);
            global = max(local,global);
        }
        return global;
    }
};
运行时间:9ms,超过31.16%
ref:http://blog.csdn.net/linhuanmars/article/details/21314059