1. 程式人生 > >LeetCode152. 乘積最大子序列

LeetCode152. 乘積最大子序列

題目

給定一個整數陣列 nums ,找出一個序列中乘積最大的連續子序列(該序列至少包含一個數)。

示例 1:

輸入: [2,3,-2,4]
輸出:6
解釋: 子陣列 [2,3] 有最大乘積 6。

示例 2:

輸入: [-2,0,-1]
輸出: 0
解釋: 結果不能為 2, 因為 [-2,-1] 不是子陣列。

分析

方法一 暴力求解

求出所有連續子串的乘積,記錄最大數字。雖然有些暴力但是還是可以通過。

時間複雜度on^2。

方法二

用三個變數,max curmax curmin 分別來 儲存 最大乘積, 當前最大乘積, 當前最小乘積。

大概思路是這樣的:遍歷序列,每到一個位置都更新當前的最大乘積和最小成績,更新最大乘積,即求出當前最優解。

計算最小乘積的意義在於,因為數字有正有負,所以最小乘積在乘上一個負數之後,就很有可能會變成一個最大乘積。

curmax = Max( nums[i], curmax*nums[i], curmin*nums[i])

curmin  = Min ( nums[i], curmax*nums[i], curmin*nums[i])

max = Max( max , curmax)

時間複雜度On

程式碼

// 方法一
class Solution {
    public int maxProduct(int[] nums) {
        int len = nums.length;
        if (len == 1) return nums[0];
        int max = Integer.MIN_VALUE;
        int[] dp = new int[len];
        for (int i = 0; i < len; i++) {
            dp[i] = nums[i];
            max = Math.max(max,nums[i]);
        }
        for (int i = 1; i < len; i++) {
            for (int j = 0; j+i < len && j < len; j++) {
                dp[j] = dp[j]*nums[j+i];
                max = Math.max(max,dp[j]);
            }
        }
        return max;
    }
}
//方法二
class Solution {
    public int maxProduct(int[] nums) {
        int max = nums[0];
        int curmax = nums[0];
        int curmin = nums[0];

        for (int i = 1; i < nums.length; i++) {
            int nextmax = nums[i] * curmax;
            int nextmin = nums[i] * curmin;
            curmax = max(nums[i], nextmax, nextmin);
            curmin = min(nums[i], nextmax, nextmin);
            max = Math.max(max,curmax);
        }
        return max;
    }
    
    public static int max(int a , int b , int c){
        return Math.max(a,Math.max(b,c));
    }
    public static int min(int a, int b, int c){
        return Math.min(a,Math.min(b,c));
    }
    
}