問題:數組
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; } }