继续刷LeetCode第53题,求一个给定数组中子序列和的最大值。
分析:
数组中子序列求和有一个规律,就是加上后面一个数后,得到的结果小于前面的数的和,那么这时增加的这个数只会使结果变小,因此就可以排除前面的数,重新在后面开始新的一轮计算。不断迭代查找到最后一个数,其中得到的数的和没有减少时,就是最大的子序列和。
问题:
1、特殊情况考虑不周到,例如如果全是负数的情况;
2、代码的简化,可读性差;
3、动态规划:将大问题分解为若干小问题,整个问题的最优解依赖于各个子问题的最优解,小问题之间存在重叠的部分,从上往下分析问题,从下往上求解问题。
附上代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int n=nums.size();
if(n==1)
return nums[0];
int s=0,tmp=nums[0];
for(int i=0;i<n;i++)
{
s=s+nums[i];
if(s>0)
{
if(s>=tmp)
tmp=s;
}
else
{
if(tmp<=nums[i])
tmp=nums[i];
s=0;
}
}
return tmp;
}
};
更好的代码:
class Solution {
public:
int maxSubArray(int A[], int n) {
int ans=A[0],i,j,sum=0;
for(i=0;i<n;i++){
sum+=A[i];
ans=max(sum,ans);
sum=max(sum,0);
}
return ans;
}
};
另外一个:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() <= 0)
{
return 0;
}
int reMax = nums[0];
int opt = nums[0];
for (int i = 1; i < nums.size(); ++i)
{
opt = opt + nums[i] > nums[i] ? opt + nums[i] : nums[i];
reMax = opt > reMax ? opt : reMax;
}
return reMax;
}
};