关于LeetCode算法题,第一题

本文详细解析了一个寻找数组中最大连续子数组乘积的问题,并通过优化算法解决了使用双层循环导致的时间效率问题。文章包括初始错误的尝试、改进的算法实现,以及关键步骤的解释,如使用最大值和最小值来处理负数的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接: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;
2.这是第一道题,想了两天的时间,中途写出了双层循环(时间复杂度为O(n2)),但是满足不了题目的要求。中途参考了另一个类似的题目,是子数组求和,这个算法的名称叫   Kadane's algorithm .可以参考网页:http://blog.youkuaiyun.com/feliciafay/article/details/18860997
3.这道题最后的答案是看了别人在Disccus里的留言才明白的。所以自己最终还是没有想出来,本来已经想到需要用max和min这一步了,但是后来实在想不下去了,所以就。。。 下次一定不允许了。
4.做题目的时候,对工作很有影响,基本上一天到晚都在想这个算法。。。 不晓得他们那些人是怎么用工作之余的时间思考的? 这个还需要加强。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值