LeetCode152 maximum-product-subarray(乘积最大子数组)
题目
Given an integer array nums, find a contiguous non-empty subarray within the array that has the largest product, and return the product.
It is guaranteed that the answer will fit in a 32-bit integer.
A subarray is a contiguous subsequence of the array.
Example 1:
Input: nums = [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: nums = [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
Constraints:
1 <= nums.length <= 2 * 10⁴
-10 <= nums[i] <= 10
The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer.
方法
动态规划法
由于数组的数字有正有负,我们讲乘积分为正数和负数讨论,max数组保存正数的情况,min数组保存负数的情况,例如:
- 当乘积m为正,当前数num[i]为正,此时max数组保存m*nums[i]为最大值
- 当乘积m为正,当前数num[i]为负,此时max数组保存num[i]作为最大值,min数组保存m*nums[i]为最小值
- 当乘积m为负,当前数num[i]为正,此时max数组保存num[i]作为最大值,min数组保存m*nums[i]为最小值
- 当乘积m为负,当前数num[i]为负,此时max数组保存m*num[i]作为最大值
以上情况包括正数和负数最大值的所有情况 - 时间复杂度:O(n)
- 空间复杂度:O(n)
class Solution {
public int maxProduct(int[] nums) {
int length = nums.length;
if(length<=0){
return 0;
}
int[] max_dp = new int[length];
int[] min_dp = new int[length];
int max = nums[0];
max_dp[0] = nums[0];
min_dp[0] = nums[0];
for(int i=1;i<length;i++){
max_dp[i] = Math.max(max_dp[i-1]*nums[i],Math.max(min_dp[i-1]*nums[i],nums[i]));
min_dp[i] = Math.min(max_dp[i-1]*nums[i],Math.min(min_dp[i-1]*nums[i],nums[i]));
max = Math.max(max,max_dp[i]);
}
return max;
}
}
动态规划法-空间优化
- 时间复杂度:O(n)
- 空间复杂度:O(1)
class Solution {
public int maxProduct(int[] nums) {
int length = nums.length;
if(length<=0){
return 0;
}
int max = nums[0],max_dp= nums[0],min_dp = nums[0];
for(int i=1;i<length;i++){
int mx = max_dp,mn = min_dp;
max_dp = Math.max(mx*nums[i],Math.max(mn*nums[i],nums[i]));
min_dp = Math.min(mx*nums[i],Math.min(mn*nums[i],nums[i]));
max = Math.max(max,max_dp);
}
return max;
}
}