题目描述:一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
方法1:求得该数组的前缀和数组,题目就变成了买卖股票的最佳时机(前缀和数组类比为股票价格)
不断遍历数组计算前缀和。当前的前缀和(卖出价格)减去之前的前缀和的最小值(买入价格),就得到了以当前元素结尾的子数组和的最大值(利润),用它来更新答案的最大值(最大利润)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int pre_sum = 0;
int min_presum = 0;
int m = nums[0];
for(int i=0;i<nums.size();i++){
pre_sum += nums[i];
m = max(pre_sum - min_presum,m);
min_presum = min(min_presum,pre_sum);
}
return m;
}
};
方法2:动态规划,d(i)表示以nums[i]结尾的最大子数组和,所以
d(i) = max(d(i-1)+ nums[i],nums[i])
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int m = nums[0];//保存最大子数组和
int dp = nums[0];
for(int i=1;i<nums.size();i++){
dp = max(dp+nums[i],nums[i]);
m = max(m,dp);
}
return m;
}
};
方法3:贪心,只保留大于0的之前和,保证当前和不会小于当前值
四个变量,当前值,之前和,当前和, 当前最大子数组和
当前和(i) = (当前值(i) + 之前和(i-1))
之前和(i) = max(0,当前和(i))
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int m = nums[0];
int nowsum = nums[0];
int presum = max(0,nums[0]);
for(int i=1;i<nums.size();i++){
nowsum = nums[i] + presum;
m = max(m,nowsum);
presum = max(0,nowsum);
}
return m;
}
};