本题大意:找出给定数组中的子数组(连续),使得所得的子数组中元素乘积在所有子数组的元素乘积中最大。例如:给定数组为:[2,3,-2,4],那么所求的连续子数组应为[2,3],它的乘积最大,为6。
解题思路:dp算法。假定当前元素为nums[j],记dp1[j]为以nums[j]为结尾的子数组的最大乘积,dp2[j]为以nums[j]结尾的子数组的最小乘积。
那么dp1[j]取决于什么呢?有三种可能:
1、当前的nums[j];2、dp1[j-1]*nums[j];3、dp2[j-1]*nums[j];
第三种情况例如,如果当前nums[j]为负数,恰好之前还有奇数个负数,就应该用之前的最小值dp2[j-1]来乘当前值nums[j]。
dp2[j]取决于什么呢?也有三种可能:
1、当前的nums[j];2、dp2[j-1]*nums[j];3、dp1[j-1]*nums[j];
第三种情况例如,如果当前nums[j]为负数,恰好之前还有偶数个负数,就应该用之前的最大值dp1[j-1]来乘当前值nums[j]。
代码如下:
1 class Solution { 2 public: 3 int maxProduct(vector<int>& nums) { 4 if(nums.empty()) return 0; 5 int n = nums.size(); 6 int dp1[n]; 7 int dp2[n]; 8 int maxP = nums[0]; 9 int minP = nums[0]; 10 dp1[0] = nums[0]; 11 dp2[0] = nums[0]; 12 for(int j = 1; j < n; j++) 13 { 14 dp2[j] = min(dp2[j-1]*nums[j], min(nums[j], dp1[j-1]*nums[j])); 15 dp1[j] = max(dp1[j-1]*nums[j], max(nums[j], dp2[j-1]*nums[j])); 16 maxP = max(maxP, dp1[j]); 17 } 18 return maxP; 19 } 20 };