O(N^2)解法
先说最朴质的解法,无非是遍历然后计算出所有的积,一一比较找到最大的罢了,跟和的第一种解法对应,于是我写下了这段代码:
int maxProduct(int A[], int n) {
int max = A[0];
for (int i = 1; i < n; ++i) {
int product = 1;
for (int j = i; j < n; ++j) {
product *= A[j];
if (product > max) {
max = product;
}
}
}
return max;
}
根据leetcode的尿性,这样的解法肯定是超时的,果不其然,提交就超时。
O(N)解法
我没有去看怎么弄出一个o(nlgn)的解法,受到上面那个博客里第三解法的启发,在求最大子序列和的时候,递推公式是:Max[i] = max(Max[i-1] * A[i], A[i])。
仔细想想,积应该不光是这样,因为存在负负得正的乘法规则,所以 Max[i] 有可能是 i-1 中的负数积乘以 A[i] 得到,表征这样一种可能性,我们需要记录前 i-1 中的最小积,其实如果那个最小的积不是负数又或者就没有必要,所以
if (Min[i-1] < 0 && A[i] < 0)
Max[i] = max(Max[i-1] * A[i], Min[i-1] * A[i])
else
Max[i] = max(Max[i-1] * A[i], A[i])
为了代码的简洁,懒得去判断正负号了,总之:Max[i] = max(Max[i-1] * A[i], Min[i-1] * A[i], A[i])。这样就可以写代码:
int max3(int a, int b, int c)
{
if ((a >= b) && (a >= c))
return a;
return max3(b, c, a);
}
int min3(int a, int b, int c)
{
if ((a <= b) && (a <= c))
return a;
return min3(b, c, a);
}
int maxProduct(int A[], int n) {
int max = A[0];
int maxtemp = A[0], mintemp = A[0];
int temp1 = 0, temp2 = 0;
for (int i = 1; i < n; ++i) {
temp1 = maxtemp * A[i];
temp2 = mintemp * A[i];
maxtemp = max3(temp1, temp2, A[i]);
mintemp = min3(temp2, temp1, A[i]);
if (maxtemp > max)
max = maxtemp;
}
return max;
}