难度中等530
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数组来完成。用f[i]来保存计算到第i个时的最大值,用g[i]来保持计算到第i个时的最小值。
- 在得出了第i-1的dp值之后,即包含i-1的可能值区间为[g[i-1],f[i-1]](左闭右闭区间)。我们考虑第i个数的情况。
- 若nums[i]为正数,可能值区间为[g[i-1]×nums[i],f[i-1]×nums[i]],和nums[i]。
- 若nums[i]为负数,可能值区间为[f[i-1]×nums[i],g[i-1]×nums[i]],和nums[i]。
- 所以我们直接根据上述的情况,就能得出包含nums[i]的最大值f[i]=max(max(f[i-1]×nums[i], g[i-1]×nums[i]), nums[i])。同理,g[i]=min(min(f[i-1]*×[i], g[i-1]×nums[i]), nums[i])。
- 最后由于我们要求的是最大值,直接对f数组取最大值即可。
复杂度分析
- 时间复杂度
O(n)
- 枚举了数组的长度
- 空间复杂度
O(n)
- 消耗了等长的空间
class Solution {
public int maxProduct(int[] nums) {
int[] max = new int[nums.length];
int[] min = new int[nums.length];
if(nums.length == 0){
return 0;
}
if(nums.length == 1) {
return nums[0];
}
max[0] = nums[0];
min[0] = nums[0];
for(int i = 1; i < nums.length;i++) {
if(nums[i] > 0) {
max[i] = Math.max(nums[i],nums[i] * max[i-1]);
min[i] = Math.min(nums[i],nums[i] * min[i - 1]);
} else {
max[i] = Math.max(nums[i],nums[i] * min[i-1]);
min[i] = Math.min(nums[i],nums[i] * max[i-1]);
}
}
int ans = 0;
for(int i = 0; i < nums.length;i++) {
ans = Math.max(ans,max[i]);
}
return ans;
}
}