牛客对应题目链接:连续子数组最大和_牛客题霸_牛客网 (nowcoder.com)
力扣对应题目链接:53. 最大子数组和 - 力扣(LeetCode)
核心考点 :简单动归问题。
一、《剑指Offer》对应内容
二、分析题目
1、贪心
从前往后迭代,一个个数字加过去,如果 sum<res,则重新开始找子序串。
2、动态规划
- 定义状态 dp[i]:表示以 i 下标结尾的最大连续子序列的和。
- 状态递推:dp[i] = max(dp[i-1]+array[i], array[i]) 【 注意:这里一定要连续关键字】
- 状态的初始化:dp[0] = array[0], max = array[0]
很明显,上面的这个做法只会使用到 dp[i] 和 dp[i-1],所以是有优化的可能的。
三、代码
//牛客
#include <iostream>
using namespace std;const int N=2e5+10;
int arr[N], dp[N];int main()
{int n;cin >> n;for(int i=0; i<n; i++) cin >> arr[i];dp[0]=arr[0];int res=arr[0];for(int i=1; i<n; i++){dp[i]=max(dp[i-1]+arr[i], arr[i]);res=max(res, dp[i]);}cout << res << endl;return 0;
}//基于上面代码的优化
#include <iostream>
using namespace std;const int N=2e5+10;
int arr[N];int main()
{int n;cin >> n;for(int i=0; i<n; i++) cin >> arr[i];int sum=arr[0];int res=arr[0];for(int i=1; i<n; i++){if(sum>=0) sum+=arr[i];else sum=arr[i];res=max(res, sum);}cout << res << endl;return 0;
}
//力扣
//方法一
class Solution {
public:int maxSubArray(vector<int>& nums) {int res=-2e4;int sum=0;for(int i=0; i<nums.size(); i++){sum+=nums[i];if(sum>res)res=sum;if(sum<0)sum=0;}return res;}
};//方法二(与上面牛客的写法不太一样)
class Solution {
public:int maxSubArray(vector<int>& nums) {int n=nums.size();vector<int> dp(n+1);int res=-2e4;for(int i=1; i<=n; i++){dp[i]=max(nums[i-1], dp[i-1]+nums[i-1]);if(dp[i]>res) res=dp[i];}return res;}
};