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;
    }
}

 

posted @ 2017-11-15 03:55  jasminemzy  阅读(108)  评论(0编辑  收藏  举报