微软面试题: LeetCode 152. 乘积最大子数组 出现次数:2

 

 解析:参考 LeetCode 评论区 liweiwei1419 大神的题解

https://leetcode-cn.com/problems/maximum-product-subarray/solution/dong-tai-gui-hua-li-jie-wu-hou-xiao-xing-by-liweiw/

使用 二维 dp 数组定义状态  

时间:O(n)  空间O(n)

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 class Solution {
 4 public:
 5     int maxProduct(vector<int>& nums)
 6     {
 7         //定义状态 dp[i][0]  以nums[i]结尾的乘积最大的子序列的乘积
 8         //定义状态 dp[i][1]  以nums[i]结尾的乘积最小的子序列的乘积
 9         vector<vector<int> > dp(2,vector<int>(nums.size()));
10         //状态初始化 dp[i][0]、dp[i][1]都初始化为nums[i],对应子序列只包含 nums[i]一个元素
11         dp[0] = nums;
12         dp[1] = nums;
13         int res = dp[0][0];
14         for(int i = 1; i < nums.size();++i)
15         {
16             if(nums[i] > 0)
17             {
18                 dp[i][0] = max(nums[i],nums[i] * dp[i-1][0]);
19                 dp[i][1] = max(nums[i],nums[i] * dp[i-1][1]);
20             }
21             else if(nums[i] < 0)
22             {
23                 dp[i][0] = max(nums[i],nums[i] * dp[i-1][1]);
24                 dp[i][1] = max(nums[i],nums[i] * dp[i-1][0]);
25             }
26             else
27             {
28                 dp[i][0] = 0;
29                 dp[i][1] = 0;
30             }
31             res = max(res,dp[i][0]);
32         }
33         return res;
34     }
35 };

由于后一次状态的更新只用到了前一次的状态,可以对二维的状态数组压缩,使用两个变量表示

dp_1 表示    以前一个元素 nums[i-1] 结尾的乘积最大的子序列的乘积

dp_12表示    以前一个元素 nums[i-1] 结尾的乘积最小的子序列的乘积

时间:O(n)  空间O(1)

代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 class Solution {
 4 public:
 5     int maxProduct(vector<int>& nums)
 6     {
 7         int dp_1 = nums[0];
 8         int dp_2 = nums[0];
 9         int res = nums[0];
10         for(int i = 1; i < nums.size();++i)
11         {
12             if(nums[i] > 0)
13             {
14                 dp_1 = max(nums[i],nums[i] * dp_1);
15                 dp_2 = min(nums[i],nums[i] * dp_2);
16             }
17             else if(nums[i] < 0)
18             {
19                 int dp_1_tmp = dp_1;
20                 dp_1 = max(nums[i],nums[i] * dp_2);
21                 dp_2 = min(nums[i],nums[i] * dp_1_tmp);
22             }
23             else
24             {
25                 dp_1 = 0;
26                 dp_2 = 0;
27             }
28             res = max(res,dp_1);
29         }
30         return res;
31     }
32 };

 

posted @ 2021-04-12 12:41  谁在写西加加  阅读(80)  评论(0编辑  收藏  举报