类似于前面的53题:最大子序和
设max(i) 为(0, i] 的最大子序乘积,由于该最大自序乘积有三种可能,max(i-1)可能是正数,负数;nums[i]也可能是正数,负数
如果是负数,要用(0, i]的最小值相乘
所以还需要设置一个函数:min(i)为(0, i]的最小子序乘积
可以得出如下的递推公式:
max(i) = Math.max( max(i-1)*nums[i], Math.max(min(i-1)*nums[i], nums[i]) ); i>=1
min(i) = Math.min( max(i-1)*nums[i], Math.min(min(i-1)*nums[i], nums[i]) ); i>=1
max(0) = min(0) = nums[0]
动态规划解法如下:
public class Test152 {
@Test
public void test() {
int[] nums = new int[]{2,3,-2,4};
System.out.println(maxProduct(nums));
}
public int maxProduct(int[] nums) {
int maxValue = nums[0];
int[] max = new int[nums.length];
max[0] = nums[0];
int[] min = new int[nums.length];
min[0] = nums[0];
for(int i=1; i<nums.length; i++) {
max[i] = Math.max(min[i-1]*nums[i], Math.max(max[i-1]*nums[i], nums[i]));
min[i] = Math.min(min[i-1]*nums[i], Math.min(max[i-1]*nums[i], nums[i]));
maxValue = Math.max(maxValue, max[i]);
}
return maxValue;
}
}