题意:如题,求最大子序和
思考:四种写法
写法一:三层暴力循环o(n^3) ---超时WA
前两层对子序列左端点l,右端点遍历r,最内部的一层循环求该【l,r】子序列的和。
//暴力法---超时
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max_ans=nums[0];
for(int i=0;i<nums.size();i++){//子序列的l
for(int j=i;j<nums.size();j++){//子序列的r
int ans=0;
for(int h=i;h<=j;h++){//子序列的和
ans+=nums[h];
}
max_ans=max(max_ans,ans);//求最大子序列
}
}
return max_ans;
}
};
写法二:暴力改进o(n^2) ---AC
我们可以省略最内部求该【l,r】子序列的和的循环。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max_ans=nums[0];
for(int i=0;i<nums.size();i++){//子序列的l
int ans=0;
for(int j=i;j<nums.size();j++){//子序列的r
ans+=nums[j];
max_ans=max(max_ans,ans);//求最大子序列
}
}
return max_ans;
}
};
写法三:扫描法o(n) ---AC
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max_ans=nums[0];
int ans=nums[0];
for(int i=1;i<nums.size();i++){
if(ans<0) ans=nums[i];//说明前面加的数是一个很大的负数,导致其和变为负数。这时ans从该数作为ans的初值
else ans+=nums[i];
max_ans=max(max_ans,ans);
}
return max_ans;
}
};
写法四:DP o(n)
sum[i]即以i结尾的最大子序和的值
sum[i]=(sum[i-1]+nums[i] , nums[i])
该题不需要另开一个sum数组,只需用到前一个sum值。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max_ans=nums[0];
int ans=nums[0];
for(int i=1;i<nums.size();i++){
if(ans>0) ans+=nums[i];
else ans=nums[i];
max_ans=max(max_ans,ans);
}
return max_ans;
}
};