最大子数组和(动态规划)
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1] 输出:1
示例 3:
输入:nums = [5,4,-1,7,8] 输出:23
思路: 动态规划
我们用 f(i) 代表以第 i 个数结尾的「连续子数组的最大和」,那么很显然我们要求的答案就是:max{f(i)} (0<i<n)
因此我们只需要求出每个位置的 f(i),然后返回 f 数组中的最大值即可。那么我们如何求 f(i) 呢?我们可以考虑 nums[i] 单独成为一段还是加入 f(i−1) 对应的那一段,这取决于 nums[i] 和 f(i−1)+nums[i] 的大小,我们希望获得一个比较大的,于是可以写出这样的动态规划转移方程:
f(i)=max{f(i−1)+nums[i],nums[i]}
class Solution { public: int maxSubArray(vector<int>& nums) { //动态规划 int n = nums.size(); vector<int> dp(n,0); dp[0] = nums[0]; int maxValue = dp[0]; for(int i=1;i<n;i++){ dp[i] = max(dp[i-1]+nums[i],nums[i]); if(dp[i]>maxValue) maxValue = dp[i]; } return maxValue; } };
方法二:前缀和+最小前缀和
class Solution { public: int maxSubArray(vector<int>& nums) { //前缀和 int n = nums.size(); int pre_sum=0,min_pre_sum=0; int ans=INT_MIN; for(int i=0;i<n;i++){ pre_sum +=nums[i]; ans = max(ans,pre_sum-min_pre_sum); min_pre_sum = min(min_pre_sum,pre_sum); } return ans; } };
浙公网安备 33010602011771号