152. Maximum Product Subarray

比较典型的动态规划。一刷的时候看code_ganker做法,对他局部 全局的想法很震惊,五体投地。

让乘积最大有2种来源:
2个正数相乘,越来越大。
2个负数相乘,也可以变大。

所以最终结果可能是正数乘以正数,也可能是一个非常小的负数乘以另一个负数,然后一下子牛逼了。。

所以既需要保留最大的正数,也需要保留最小的负数。

public class Solution 
{
    public int maxProduct(int[] nums) 
    {
        if(nums.length == 0) return 0;
        
        int global = nums[0];
        int max = nums[0];
        int min = nums[0];
        
        for(int i = 1; i < nums.length;i++)
        {
            int temp = max;
            max = Math.max(nums[i] * min,  Math.max(nums[i],nums[i] * max));
            min = Math.min(nums[i] * temp,  Math.min(nums[i],nums[i] * min));
            
            global = Math.max(global,max);
        }
        
        return global;
    }
}

global就不解释了,每次比较取最大。

max是局部最大值,如果写成DP是localMax[i],表示包含nums[i]的最大值。

可以是localMax[i-1]*nums[i],例子是前面是正的,当前nums[i]也是正的;  
可以是nums[i],前面是负的,nums[i]是正的,那我干脆不要前面的了,就要现在的正数。
还有种可能是,前面是负的,现在也是负的,就是localMin[i-1] * nums[i]  
这3种情况取最大。

min是对应的局部最小,和上面的算法正好相反。
然后每次取一下global

如果不能理解,可以先尝试写成localMax[] localMin[],

localMax[i] = nums[i],  localMax[i-1]*nums[i]  , localMin[i-1]*nums[i]. 里面最大的。
localMin[i] 一样。
原文地址:https://www.cnblogs.com/reboot329/p/5876081.html