【LEETCODE】152.乘積最大子數組

題目

給定一個整數數組 nums ,請你找出數組中乘積最大的連續子數組(該子數組中至少包含一個數字),並返回該子數組所對應的乘積。

思路

使用動態規劃方法。
最樸素的想法,需要將每一種子數組都考慮到,即時間複雜度爲O(n^2)
如何降低時間複雜度呢?最理想化的算法也需要遍歷一次數組,即O(n)
求相鄰數組的最大值,在第i個位置只有兩種取值的可能性:
(1)取nums[i]值;
(2)nums[i-1]時的最大值與nums[i]相乘,即maxNum[i-1]*nums[i];
此題還有一個特殊情況,就是數組可以取負值,若nums[i]爲負值,則最大值的取值兩種情況爲:
(1)取nums[i]值;
(2)nums[i-1]時的最小值與nums[i]相乘,即minNum[i-1]*nums[i];
因此需要兩個數組分別存儲數組的最大值和最小值,以此來求出整個數組的子區間最大值。

代碼

class Solution {
    public int maxProduct(int[] nums) {
        //算法複雜度O(n^2)->O(n)
        //只掃描1次
        int len = nums.length;
        int max = nums[0];
        int[] maxNum = new int[len];
        int[] minNum = new int[len];
        maxNum[0]=nums[0];
        minNum[0]=nums[0];
        for(int i=1; i<len; i++){
            if(nums[i]>=0){
                maxNum[i] = Math.max(nums[i],maxNum[i-1]*nums[i]);
                minNum[i] = Math.min(nums[i],minNum[i-1]*nums[i]);
            }else{
                maxNum[i] = Math.max(nums[i],minNum[i-1]*nums[i]);
                minNum[i] = Math.min(nums[i],maxNum[i-1]*nums[i]);
            }
           
            max = Math.max(max,maxNum[i]);
        }
        return max;
    }
}

複雜度分析

  1. 時間複雜度:O(n)
  2. 空間複雜度:O(n)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章