Maximum Product Subarray@LeetCode

Maximum Product Subarrayjava

一開始題目沒有看清楚,覺得仍是求和,可是這一題實際上是求乘積,那麼相對於求和的題目,求乘積須要注意的有兩點:數組

  • 元素爲0的點,只要包含了元素爲0的點,那麼整段的乘積必爲0
  • 正負數,不能簡單地依靠動態規劃的方法作,由於以後的信息對以前的信息是有影響的:i點以前的乘積爲負數,但若是以後還有負數,則乘積會變成正數且將大於以前的乘積

解題的思想以下:code

  1. 以0爲界,分割數組,計算每一個0之間(以及0和短點之間)的乘積
  2. 針對每一段乘積,若是乘積爲正數,則直接返回與當前最大值比較;若是乘積爲負數,則取最短負數前綴和最短負數後綴(連續的乘積爲負的數字段),分別用整段乘積去除以後就能獲得該段最大乘積

代碼以下:leetcode

javapublic class Solution {
    public int maxProduct(int[] A) {
        int max = A[0], length = A.length;
        int begin = 0, end, product;
        while (begin < length && A[begin] == 0) {
            begin++;
        }
        if (begin == length)
            return 0;
        end = begin + 1;
        product = A[begin];
        while (end < length) {
            if (A[end] == 0) {
                max = Math.max(max, Math.max(0, countMax(begin, end, A, product)));
                begin = end + 1;
                while (begin < length && A[begin] == 0) {
                    begin++;
                }
                if (begin == length)
                    break;
                product = A[begin];
                end = begin + 1;
            } else {
                product *= A[end++];
            }
        }
        if (begin != length)
            max = Math.max(max, countMax(begin, length, A, product));
        return max;
    }

    private int countMax(int begin, int end, int[] A, int product) {
        if (product > 0 || end - begin == 1) {
            return product;
        }
        int index = begin;
        int preProduct = 1, sufProduct = 1;
        while (index < end - 1 && A[index] > 0) {
            preProduct *= A[index];
            index++;
        }
        preProduct *= A[index];
        index = end - 1;
        while (begin < index && A[index] > 0) {
            sufProduct *= A[index];
            index--;
        }
        sufProduct *= A[index];
        return Math.max(product / preProduct, product / sufProduct);
    }
}
相關文章
相關標籤/搜索