题目:
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
class Solution {
public:
// int maxSubArray(vector<int>& nums)
// {
// // 贪心算法: 因为负数总是会拉低总和,所以当遇到负数,就将 sum 清0,
// // result 中一直更新最大的 sum ,这样遍历一遍之后得到的就是 最大自序和
// int result = INT_MIN;
// int sum = 0;
// for(int i = 0; i < nums.size(); i++)
// {
// sum += nums[i];
// // result 在遍历中不断更新,保留最大的和
// result = result > sum ? result : sum;
// // 如果 sum 等于 0 ,那么就表示有负数,那这个负数肯定是拉低总和的,弃之
// if(sum <= 0)
// {
// sum = 0;
// }
// }
// return result;
// }
// 动态规划
/*
注意子数组即是连续子序列,注意连续的问题,在中间过程中就需要记录中间过程中的最大值,
因为一旦不符合情况,就需要从 0 开始计数。
1、确定dp数组以及下标的含义
dp[i] 表示包括 i 之前的最大连续子序列的和为 dp[i]
2、确定递推公式
dp[i] 由两个方向推导而来
若需要nums[i],则 dp[i] = dp[i-1] + nums[i]
若不需要nums[i],则就开始从头计算当前连续子序列
3、dp 数组的初始化
dp[0] = nums[0]
其余的初始化为0即可
4、确定遍历顺序
因为dp[i]依赖于dp[i-1]的状态,所以需要从前往后遍历
*/
int maxSubArray(vector<int>& nums)
{
if(nums.size() == 0)
{
return 0;
}
// 第一次见 dp 数组,dp[i] 表示包括 i 之前的最大连续子序列和
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
int result = dp[0];
// 动态规划的起始下标设为了 1,
// debug 的时候 overflow 敏锐一点,就看循环嘛
for(int i = 1; i < nums.size(); i++)
{
dp[i] = max(dp[i - 1] + nums[i], nums[i]); // 状态转移公示
result = result > dp[i] ? result : dp[i]; // 更新 result为最大值
}
return result;
}
};