• 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 };
  • 相关阅读:
    python 字符串中的%s与format
    python中的virtualenv是干嘛的?
    grep 与 find 简单命令
    git merge 和 git rebase的区别
    git stash的用法
    git push的用法
    git pull与git fetch的区别
    辟谣平台 踩坑记(一)
    微信JS-SDK开发 入门指南
    linux 写U盘出现的问题
  • 原文地址:https://www.cnblogs.com/zle1992/p/10415601.html
Copyright © 2020-2023  润新知