问题描述:
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.</p>
这题开始以为用DP可以解决,但是仔细想了想,每次子问题的解不可以重复利用。因此,DP应该解决不了。如果有解决的,请@我。
思路:
数字只有三种情况,正数,负数,0;
遇到有0的,数组肯定前后分开。即[数组A,0,数组B]。然后在数组A和B之间找出最大值。因此,我们只需要考虑正数和负数交叉的情况。
我们知道,连在一起的正数可以看作一个数,负数不行。原因[-5,1,-2,-1]明显[-2,-1]不能看作一个数。
对于存在负数的情况,我们只需要判断如下两种情况就行了。
1.数组开始到最后一个负数前一个数,
2.数组的第一个负数+1为到数组最后一个数即可。
中间判断下开始和结束位大小。最终判断1.2的大小,存到一个List里面(因为存在0的情况,所以每个分组都有最大值)。
最后从这个最大值的List找到一个最大的就行了。
下面代码已过Leetcode.
package Max_Product_Subarray;
import java.util.List;
import java.util.ArrayList;
public class Max_Product_Subarray {
/**
* 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 static void main(String[] args) {
// TODO Auto-generated method stub
int[] A = {-1,-2,-3,0};
Max_Product_Subarray mps = new Max_Product_Subarray();
System.out.println(mps.maxProduct(A));
}
public int theProduct(int start,int end,int[] A){
int result = 1;
for(int i=start;i<=end;i++)
result=result*A[i];
return result;
}
public int max(int m,int n){
return m>n?m:n;
}
/**
* 首先明确数字可能是正数、负数、0,其中相连的正数可看做整体,如此,只判断A[]中负数情况和0的情况:
* 1.A中负数为0,零的个数为0 ------> 最大值:整个A相乘
* |-- 负数为偶数, 整个A相乘
* 2.A中负数不为0,零的个数为0 ---
* |-- 负数为奇数,数目为n,判断两种情况的最大值:从头乘到n-1负数的前一个书;or 从第一个负数后开始*到最后一个负数
* 3零的个数不为0;按0分割成小模块,判断所有小模块的最大值
* */
public int maxProduct(int[] A) {
if(A.length==1)
return A[0];
List<Integer> zero = new ArrayList<Integer>();
for(int i=0;i<A.length;i++){
if(A[i]==0)
zero.add(i);
}
List<Integer> maxArray = new ArrayList<Integer>();
if(zero.size()==0)
maxArray.add(comProduct(0,A.length-1,A)) ;
else{
int i = 0;
for( i=0;i<zero.size();i++)
if(i==0)
maxArray.add(comProduct(0,zero.get(i)-1,A));
else{
maxArray.add(comProduct(zero.get(i-1)+1, zero.get(i)-1, A));
}
maxArray.add(comProduct(zero.get(i-1)+1, A.length-1, A));
}
int max = -2147483648;
for(int temp:maxArray){
if(temp>max)
max=temp;
}
return max>0?max:0;
}
public int comProduct(int start,int end,int[] A){
System.out.println("start ="+start+" end "+end);
if(end<start)
return -2147483648;
if(end==start)
return A[end];
List<Integer> op = new ArrayList<Integer>();
for(int i=start;i<=end;i++)
if(A[i]<0)
op.add(i);
//判断A中负号的个数
if(op.size()%2==0)
return theProduct(start,end,A);
else{
System.out.println("op.size()-1 "+(op.size()-1)+" op.get(0)+1 "+(op.get(0)+1));
return max(theProduct(start,op.get(op.size()-1)-1,A),theProduct(op.get(0)+1,end,A));
}
}
}