zoukankan      html  css  js  c++  java
  • leetcode152- Maximum Product Subarray- medium

    Find the contiguous subarray within an array (containing at least one number) which has the largest product.

    For example, given the array [2,3,-2,4],

    the contiguous subarray [2,3] has the largest product = 6.

    public int maxProduct(int[] nums) 

    这题不好和前面max sum的题一样用前缀法,因为乘法特殊,如果乘了0就把以前以后的信息都消去了,如0,1,1,2,3,4,5,4,3,乘后全是0,无法用两者相除来得到这一段区间的乘积信息

    算法:小DP。max[], min[]定义是从这个点开始向前连续任意长度的数组乘积最大值最小值。最后不是返回max[length - 1],而是返回过程中打擂台胜出的值。这样又可以做到允许间断(打擂台),又可以做到轻松地写出状态转移方程(因为你加了存储的值是连续的这个限制)。

    细节:1.乘法和当前数是正数负数还是0有关,正数的话当前连续最大值是max[i] = nums[i] * max[i - 1],负数的话是max[i] = nums[i] * min[i - 1],零的话连续肯定0。这点小心。

    2.可以做一个空间变O(1)的优化,因为每次计算只和前一个有关,没必要全纪录下来,所以用min,max,minPre,maxPre,result即可,不过这里pre不是说前缀,只是前一个的意思。

    1.O(n)空间

    class Solution {
        public int maxProduct(int[] nums) {
            
            int[] max = new int[nums.length];
            int[] min = new int[nums.length];
            
            max[0] = min[0] = nums[0];
            int result = 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 if (nums[i] < 0) {
                    max[i] = Math.max(nums[i], nums[i] * min[i - 1]);
                    min[i] = Math.min(nums[i], nums[i] * max[i - 1]);
                }
                result = Math.max(result, max[i]);
            }
            return result;
        }
    }

    2.O(1)空间

    class Solution {
        public int maxProduct(int[] nums) {
            
            if (nums == null || nums.length == 0) {
                return 0;
            }
            
            int preMax = nums[0], preMin = nums[0];
            int max = nums[0], min = nums[0];
            int result = nums[0];
            for (int i = 1; i < nums.length; i++) {
                if (nums[i] > 0) {
                    max = Math.max(nums[i], nums[i] * preMax);
                    min = Math.min(nums[i], nums[i] * preMin);
                } else if (nums[i] < 0) {
                    max = Math.max(nums[i], nums[i] * preMin);
                    min = Math.min(nums[i], nums[i] * preMax);
                } else {
                    max = min = 0;
                }
                result = Math.max(result, max);
                preMax = max;
                preMin = min;
            }
            return result;
        }
    }
  • 相关阅读:
    博客诞生感言~
    java 字符串锁
    oracle三种表连接方式
    两张超级大表join优化
    docker安装配置gitlab详细过程
    docker安装应用
    docker安装教程-centos
    JVM参数调优
    java向word中插入Excel附件
    application.properties参数详解
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7837124.html
Copyright © 2011-2022 走看看