152.乘积最大子数组

image-20200518202521844

枚举

思路

  • 遍历所有情况,不断更新最大值
  • 能解题,但时间复杂度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;
    }

动态规划

思路

参考画解算法:152.乘积最大子序列

  • 遍历数组时计算当前最大值,不断更新
  • 令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;
    }

小结

​ 需注意的是正负符号 影响 子最优解,需及时调整。本题中,乘以负数时,最大值变最小值,最小值变最大值。与以往题型只记录一个最值不同,该题需记录当前最小和最大值。

猜你喜欢

转载自www.cnblogs.com/yh-simon/p/12912854.html