【Leetcode】152. Maximum Product Subarray

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 解題步驟

  1. 設計暴力算法,找到冗余
  2. 設計并存儲狀態(一維,二維,三維數組,甚至Map)
  3. 遞歸式(狀態轉移方程)
  4. 自底向下計算最優解(編程方式)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容