152. Maximum Product Subarray(动态规划)



Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.

Example 1:

Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.

Example 2:

Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.



由于负数的存在,需要同时保存当前最大值和当前最小值,所以需要维护两个DP表,可以分别表示为dp_min和dp_max。所以即为dp_max里的最大值。

需要维护的当前最大值和当前最小值,都是在dp_min[i-1] * A[i],dp_max[i] * A[i],和A[i]这三者里面取一即可。有了这个只关乎最终状态,不关乎过程细节的结论,解题过程可以大大简化。

 

 

 1  class Solution {
 2  public:
 3      int maxProduct(vector<int>& nums) {
 4           int n = nums.size();
 5           if(n==0) return 0;
 6           vector<int>dp_max(n,nums[0]);
 7           vector<int>dp_min(n,nums[0]);
 8   
 9           int res_val = nums[0];
10          for(int i =1;i<n;i++){
11              dp_max[i] = std::max( std::max(dp_max[i-1]*nums[i],dp_min[i-1]*nums[i]),    nums[i]);
12              dp_min[i]= std::min( std::min(dp_min[i-1]*nums[i],dp_max[i-1]*nums[i]),    nums[i]);
13             
14          }
15          for(int i =0;i<n;i++)
16                 res_val = std::max(dp_max[i],res_val);
17          return res_val;
18      
19      }
20  };

 

 

思考以上DP解法的空间开销过大的原因,是因为保存了整个DP表。其实整个过程中,获得dp[i]的值只需要dp[i-1]的值,所以是不需要保存整个DP表的。

这样一来,DP可以用滚动数组进行优化。简单的写法其实就是设一对prevMin/prevMax表示上一个值,以及还有一对curMin/curMax表示当前值。

 

 1 class Solution {
 2 public:
 3     int maxProduct(vector<int>& nums) {
 4         int n = nums.size();
 5         if(n==0) return 0;
 6         int dp_max_pre = nums[0];
 7         int dp_min_pre = nums[0];
 8         int dp_max;
 9         int dp_min;
10 
11         int res_val = nums[0];
12         for(int i =1;i<n;i++){
13             dp_max = std::max( std::max(dp_max_pre*nums[i],dp_min_pre*nums[i]),    nums[i]);
14             dp_min= std::min( std::min(dp_max_pre*nums[i],dp_min_pre*nums[i]),    nums[i]);
15             res_val =std::max(res_val,dp_max);
16             dp_max_pre = dp_max;
17             dp_min_pre = dp_min;
18         }
19          
20         return res_val;
21     
22     }
23 };

 

转载于:https://www.cnblogs.com/zle1992/p/10415601.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值