題目
給定一個整數數組 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;
}
}
複雜度分析
- 時間複雜度:O(n)
- 空間複雜度:O(n)