枚举
思路
- 遍历所有情况,不断更新最大值
- 能解题,但时间复杂度O(n^2)
代码
/**
* 120ms
*/
public int maxProduct(int[] nums) {
int ans=Integer.MIN_VALUE;
for(int i=0;i<nums.length;i++){
int mult=1;
for(int j=i;j<nums.length;j++){
mult*=nums[j];
ans=Math.max(ans, mult);
}
}
return ans;
}
动态规划
思路
- 遍历数组时计算当前最大值,不断更新
- 令imax为当前最大值,则当前最大值为
imax=Math.max(imax*nums[i],nums[i])
- 由于存在负数,那么乘以负数 会导致最大的变最小的,最小的变最大的。因此需要维护当前最小值imin,
imin=Math.min(imin*nums[i],nums[i])
- 若当前遍历值为负数 则imax与imin先交换 再进行计算
- 时间复杂度 O(n)
代码
/**
* 2ms
* 动态规划
*/
public int maxProduct2(int[] nums){
//imax为当前最大值
int max=Integer.MIN_VALUE,imax=1,imin=1;
for(int i=0;i<nums.length;i++){
//若当前遍历值为负数 则imax与imin先交换 再进行计算
if(nums[i]<0){
int tmp=imax;
imax=imin;
imin=tmp;
}
imax=Math.max(imax*nums[i],nums[i]);
imin=Math.min(imin*nums[i],nums[i]);
max=Math.max(max, imax);
}
return max;
}
小结
需注意的是正负符号 影响 子最优解,需及时调整。本题中,乘以负数时,最大值变最小值,最小值变最大值。与以往题型只记录一个最值不同,该题需记录当前最小和最大值。