• 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;
        }
    }
  • 相关阅读:
    kafka 常见面试题
    分布式-redis实现分布式锁
    java info信息中打印异常堆栈
    11.盛水最多的容器
    445.两数相加
    328. 奇偶链表
    7中join查询
    Linux基础学习05
    Linux基础学习04
    Linux基础学习03
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7837124.html
Copyright © 2020-2023  润新知