152. Maximum Product Subarray
Given an integer array nums
, find the contiguous subarray within an array (containing at least one number) which has the largest product.
Example 1:
Input: [2,3,-2,4]
Output: 6
Explanation: [2,3] has the largest product 6.
Example 2:
Input: [-2,0,-1]
Output: 0
Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
求最大子數組的乘積是由最大子數組和演變而來,但是更復雜,求和的時候,遇到 0 不會改變最大值,遇到負數最大值減小。而求乘積的時候,遇到 0 會使得整個運算結果為 0,遇到負數,會使得最大乘積變成最小乘積。
這道題簡單的辦法就是用 DP 來做,維護兩個 DP 數組,maxLocal[i] 存儲 [0,i] 最大數組乘積,minLocal[i] 存儲 [0,i] 最小數組乘積,初始化maxLocal[i] 和 minLocal[i] 為 nums[0]。
從這個數組的第二個數開始遍歷,那么此時最大值和最小值都將從 maxLocal[i - 1] * nums[i],minLocal[i] * nums[i],和 nums[i] 產生。我們用 maxLocal[i] 和 minLocal[i] 更新最大和最小值,然后我們用 global 存儲當前最大的乘積。
時間復雜度 O(n)
class Solution {
public int maxProduct(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int maxLocal[] = new int[arr.length+1];
int minLocal[] = new int[arr.length+1];
maxLocal[0] = arr[0];
minLocal[0] = arr[0];
int global = maxLocal[0];
for(int i=1;i<arr.length;i++){
maxLocal[i] = Math.max(Math.max(arr[i]*maxLocal[i-1],arr[i]*minLocal[i-1]),arr[i]);
minLocal[i] = Math.min(Math.min(arr[i]*maxLocal[i-1],arr[i]*minLocal[i-1]),arr[i]);
global = Math.max(global,maxLocal[i]);
}
return global;
}
}
DP 解題步驟
- 設計暴力算法,找到冗余
- 設計并存儲狀態(一維,二維,三維數組,甚至Map)
- 遞歸式(狀態轉移方程)
- 自底向下計算最優解(編程方式)