原题:
===========================================
#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;
}
}