题目链接:https://oj.leetcode.com/problems/maximum-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
.
题目解答过程:
半成品 提示
Time Limit Exceeded
public class Solution {
public int maxProduct(int[] A) {
int Max = 0;
int MaxArar =0;
if(A==null){
return 0;
}
int len = A.length;
Max = A[0];
for(int i = 0; i<len-1;i++){
if(Max < getMax(A[i],A[i+1])){
Max = getMax(A[i],A[i+1]);
}
}
MaxArar = getMaxArrar(A);
if(Max<MaxArar){
Max = MaxArar;
}
return Max;
}
public int getMax(int a,int b){
int max = a;
if(a<b){
max = b;
}
if(max<a*b){
max = a*b;
}
return max;
}
public int getMaxArrar(int[] A){
int tempMax = A[0];
int len = A.length;
for(int i = 0;i<len;i++){
if(tempMax<A[i])
tempMax = A[i];
for(int j = i+1;j<len;j++){
if(tempMax<tempMax*A[j]){
tempMax = tempMax*A[j];
}
}
}
return tempMax;
}
}
后改成
public class Solution {
public int maxProduct(int[] A) {
int Max = 0;
int MaxArar =0;
if(A==null){
return 0;
}
MaxArar = getMaxArrar(A);
return MaxArar;
}
public int getMaxArrar(int[] A){
int tempMax = A[0];
int len = A.length;
for(int i = 0;i<len;i++){
if(tempMax<A[i])
tempMax = A[i];
for(int j = i+1;j<len;j++){
int temp = tempMax*A[j];
if(tempMax<temp){
tempMax = temp;
}
}
}
return tempMax;
}
}
还是同样的问题, 问题可能就是用了双层循环的原因了。
他们的结果是进行一个时间复杂度为O(n)的结果,所以最终的答案是:
思路就是 取第一个值作为最大值Max1和最小值,然后将最小值和最大值(Max1)都与下一个数相乘,又可以得到新的最大值(Max2)和最小值。
得到后新的最大值Max2和之前的最大值Max1比,保留最大值(MaxFinal),而这轮的最大值(Max2) 则继续在下一轮中进行相乘。一直循环到数组的最后一个。
public class Solution {
public int maxProduct(int[] A) {
if(A==null){
return 0;
}
int len = A.length;
int max=A[0];
int min = A[0];
int tempMax = A[0];
for(int i = 1;i<len;i++){
if(A[i] == 0) {
max = 0; //we set both max and min to be 0 whenever current element is 0.
min = 0;
} else {
int maxt= max;
max = getMax3(A[i],getProduct(A[i],max),getProduct(A[i],min));
min = getMin3(A[i],getProduct(A[i],maxt),getProduct(A[i],min));
}
tempMax = getMax2(max, tempMax);
}
return tempMax;
}
public int getMax2(int a,int b){
return a>b? a:b;
}
public int getMin2(int a,int b){
return a>b? b:a;
}
public int getMax3(int a,int b ,int c){
return getMax2(getMax2(a,b),c);
}
public int getMin3(int a,int b,int c){
return getMin2(getMin2(a,b),c);
}
public int getProduct(int a,int b){
if(a<b){
getProduct(b,a);
}
int INT_MAX = java.lang.Integer.MAX_VALUE;
int INT_MIN = java.lang.Integer.MIN_VALUE;
if(a ==0||b==0){
return 0;
}
if(a>0&&b>0){
//two Negative number product may more than MAX
if(a*b>INT_MAX){
return INT_MAX;
}else{
return a*b;
}
}
if(a<0&&b<0){
//two Negative number product may more than MAX
if((b != -1) &&a*b>INT_MAX){
return INT_MAX;
}else{
return a*b;
}
}
//one Positive number and one Negative number product may less than the MIN
if(a*b <INT_MIN){
return INT_MIN;
}else{
return a*b;
}
}
}
本轮算法题总结:
1.关系到数组的运算的,要判断是否超出运算范围,设定Max 和Min.在Java中是:
int INT_MAX = java.lang.Integer.MAX_VALUE;
int INT_MIN = java.lang.Integer.MIN_VALUE;
int INT_MIN = java.lang.Integer.MIN_VALUE;
2.这是第一道题,想了两天的时间,中途写出了双层循环(时间复杂度为O(n2)),但是满足不了题目的要求。中途参考了另一个类似的题目,是子数组求和,这个算法的名称叫
Kadane's algorithm .可以参考网页:http://blog.youkuaiyun.com/feliciafay/article/details/18860997
3.这道题最后的答案是看了别人在Disccus里的留言才明白的。所以自己最终还是没有想出来,本来已经想到需要用max和min这一步了,但是后来实在想不下去了,所以就。。。 下次一定不允许了。
4.做题目的时候,对工作很有影响,基本上一天到晚都在想这个算法。。。 不晓得他们那些人是怎么用工作之余的时间思考的? 这个还需要加强。