问题:数组
Find the contiguous subarray within an array (containing at least one number) which has the largest product.spa
For example, given the array [2,3,-2,4]
,
the contiguous subarray [2,3]
has the largest product = 6
.code
解决:it
① 这个求最大子数组乘积问题是由最大子数组之和问题演变而来,可是却比求最大子数组之和要复杂,由于在求和的时候,遇到0,不会改变最大值,遇到负数,也只是会减少最大值而已。而在求最大子数组乘积的问题中,遇到0会使整个乘积为0,而遇到负数,则会使最大乘积变成最小乘积,正由于有负数和0的存在,使问题变得复杂了很多。io
这道题最直接的方法就是用DP来作,在处理乘法的时候,除了须要维护一个局部最大值,同时还要维护一个局部最小值,由此,能够写出以下的转移方程式:ast
初始:max[i] = nums[i],min[i] = nums[i];class
状态转移方程:方法
若是nums[i]是负数:co
max[i] = Math.max(min[i - 1] * nums[i], max[i]);new
min[i] = Math.min(max[i - 1] * nums[i], min[i]);
若是nums[i]是正数:
max[i] = Math.max(max[i], max[i - 1] * nums[i]);
min[i] = Math.min(min[i], min[i - 1] * nums[i]);
class Solution { //2ms
public int maxProduct(int[] nums) {
if(nums.length == 1) return nums[0];
int[] max = new int[nums.length];
int[] min = new int[nums.length];
for (int i = 0;i < nums.length;i ++){
max[i] = nums[i];
min[i] = nums[i];
}
int product = nums[0];
for (int i = 1;i < nums.length;i ++){
if (nums[i] < 0){
max[i] = Math.max(min[i - 1] * nums[i],max[i]);
min[i] = Math.min(max[i - 1] * nums[i],min[i]);
product = Math.max(max[i],product);
}else{
max[i] = Math.max(max[i - 1] * nums[i],max[i]);
min[i] = Math.min(min[i - 1] * nums[i],min[i]);
product = Math.max(max[i],product);
}
}
return product;
}
}
② 能够简化上面的代码。
class Solution { //3ms public int maxProduct(int[] nums) { if (nums == null || nums.length == 0) return 0; int product = nums[0]; int min = nums[0]; int max = nums[0]; for (int i = 1;i < nums.length;i ++){ int tmpmax = max; int tmpmin = min; max = Math.max(Math.max(nums[i],nums[i] * tmpmax),tmpmin * nums[i]); min = Math.min(Math.min(nums[i],tmpmax * nums[i]),tmpmin * nums[i]); product = Math.max(product,max); } return product; } }