Maximum Subarray
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.
题目求一个数组中和最大的子数组。第一时间我们可以想到的就是直接遍历。因为只需要求值而不需要知道是哪个子数组,所以求出数组中所有子数组的和,然后取最大值即可。
采用嵌套循环的方式,该算法的时间复杂度应该为O(n^2)(算法很简单,此处不给出了)。
这个方法虽然思路简单,但是明显不是最优解。那么有没有更好的方法呢?
我们思考一下之前提到过的分而治之思想。如何把问题转化成一个相同问题的累计?
首相想到的是求在下标i到j之间的最小子数组:max(num,i,j);但是如果将问题这么分析,那么问题无法再往下分割,一步步简化;
这里想到要求和,当然是一个个的数加起来。求和的最大值,当然要每次做加法都要越加越大:即,每次都是一个大于零的数。所以,将问题转化成max(num,j),即求以下标为j的数结尾的数组的子数组的最大值,也就是:
max(num,j) = max(num,j-1)>0 ? max(num,j-1)+num[j] : num[j]
每次的问题求最大和都是求上一次的最大和,也就是只要知道了第一次的最大和max(num,0),也就是num[0],整个数组的子数组最大和也就可以得知了。
c代码如下:
int maxSubArray(int* nums, int numsSize) {
int sum[numsSize];
sum[0] = nums[0];
int max = sum[0];
for(int i = 1;i < numsSize; i ++) {
sum[i] = nums[i] + ((sum[i-1] > 0) ? sum[i-1] : 0);
max = (max > sum[i]) ? max : sum[i];
}
return max;
}
附上LeetCode链接:https://leetcode.com/problems/maximum-subarray/description/