1、题目描述
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.
求一个数组中总和最大的子串和对应的和。
2、解题思路
给定一个数组a中有n个元素,那么它的子串就有n(n+1)/2个子串,如果使用穷举法,时间复杂度就是O(n^2),所以为了降低复杂度,使用一下两个方法解决该问题
A:这是一个线性时间算法解决该问题,对于数组a[1…n],如果a[i…j]是和最大的子串,那么对于任何k(i<=k<=j),我们有a[i…k]的元素之和大于0。如果存在a[i…k]元素之和小于0,那么就有a[k+1…j]的元素之和大于a[i…j]的元素之和,这就与最初的假设相矛盾。
首先我们讲给定数组a从左分为若干和为负的子串,最后一个可以为正,而我们求得和最大子串一定是最后一个子串的一个前缀。
这种方法不适用于全为负值的数组求解
B:动态规划方法
解题过程中我们主要考虑局部最优和全局最优的情况,前i个元素对应的局部最就是包含元素a[i]的最优子串就是lobal[i], lobal[i+1]=max(lobal[i]+a[i+1],a[i+1]),对应的全局最优就是指global[i], global[i+1]=max(global[i],lobal[i])。
3、实现代码
A:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
auto n=nums.size();
int I=0,J=0,left=0,right=0,max0=0,max=0;
for(int i=0;i<n;i++){
max0+=nums[i];
if(max0>0){
J=i;
if(max<max0){
max=max0;
left=I;
right=J;
}
}
else{
max0=0;
I=J=i+1;
}
}
return max;
}
};
B:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
auto n=nums.size();
int local=nums[0],global=nums[0];
for (int i=1;i<n;i++){
local=max(local+nums[i],nums[i]);
global=max(local,global);
}
return global;
}
};
4、结果呈现
两种方法均得到了想要的结果:
Run Code Result:×
Your input
[-2,1,-3,4,-1,2,1,-5,4]
Your answer
6
Expected answer
6
Show Diff