Leetcode-"Maximum product subarray"

原题:

Maximum product subarray

===========================================

#1 题目理解:

给出一个数组,求连续子数列乘积最大值。

比如:{1, 2, -3, 4, 5, -6, -7, 8, 9}

返回结果就是60480,从-6到9那一段。

===========================================

#2 算法:

从头到尾遍历一次,遇到0清算一次结果。
0是把sub-problem隔开的元素。

考虑不含有0的数组,设定双指针,分别记录数组里面第一个和最后一个负数。

如果数组的乘积是正数,那么这个就是最大值。如果整个数组乘积是负数,而且只有一个负数,那么选择负数左边或者右边较大者。如果有多于一个负数,考虑第一个和最后一个。假设指针分别为first和last。那么考虑first左/右和 last左/右四种情况。取较大者。

===========================================

#3 数据结构:

四个index,分别是:st, end, first, last。满足:st <= first <= last <= end

===========================================

#4 代码:

public class Solution {
    public static int maxProduct(int[] A) {
        int max = Integer.MIN_VALUE; // global maximum
        int st = 0; // index of the start of the non zero array
        int first = -1; // index of the first negative number
        int last = -1; // index of the last negative number, may be the same as the 1st one

        for (int i = 0; i < A.length; i++) {
            if (A[i] == 0) {
                if (max < 0) max = 0; // 0 might be the largest product
                if (i > st) {
                    int p = maxProductSubArr(st, i-1, first, last, A);
                    if (p > max) max = p;    
                }
                st = i + 1;
                first = -1;
                last = -1;
            } else {
                if (A[i] < 0) {
                    if (first == -1) {
                        first = i;
                        last = i;
                    } else {
                        last = i;
                    }
                }
            }
        }
        if (A.length > st) {
            int p = maxProductSubArr(st, A.length-1, first, last, A);
            if (p > max) max = p;
        }
        return max;
    }

    // return the max product in the non zero array
    public static int maxProductSubArr(int st, int end, int first, int last, int[] A) {
        int p = 1;
        for (int j = st; j <= end; j++) p *= A[j];
        if (p > 0) return p;

        int max = A[st]; // fail test case [-2] if set max = Integer.MIN_VALUE
        if (first > st) {
            p = 1;
            for (int j = st; j < first; j++) p *= A[j];
            if (p > max) max = p;
        }
        if (end > first) {
            p = 1;
            for (int j = first + 1; j <= end; j++) p *= A[j];
            if (p > max) max = p;
        }
        if (last > st) {
            p = 1;
            for (int j = st; j < last; j++) p *= A[j];
            if (p > max) max = p;
        }
        if (end > last) {
            p = 1;
            for (int j = last + 1; j <= end; j++) p *= A[j];
            if (p > max) max = p;
        }
        return max;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值