题目:
Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4]
, the contiguous subarray [2,3]
has the largest product = 6
.
思路:
这道题的原型是求最大和的子序列,二者差别主要在于乘法和加法不太一样,如果是加法,动态规划只要设置一个保存最大值的一维数组f[N],如果f[i]>0,那么f[i+1]=f[i]+A[i],否则f[i+1]=A[i],现在变成了乘法,显然不能直接套用加法的思路,因为f[i+1]不能直接从f[i]和A[i+1]推导出来,还需要看A[0-i]。
最暴力的解法很简单,就是把所有子序列A[i]*...A[j]迭代算出来,然后找到最大的,不过提交之后呵呵,很自然的内存爆了。。。
最后AC的思路又是参考了别人的博客。。。在动态规划迭代维护一个局部最大的同时,再维护一个局部最小,这样如果下一个元素遇到负数时,就可能与这个最小相乘得到当前最大的乘积和,然后每次迭代过程再维护一个全局最大值。
C++代码如下,其中maxProduct为AC的代码,maxProduct1为暴力算法:
#include <iostream> #include <vector> #include <stdlib.h> #include <time.h> using namespace std; class Solution { public: long min(long x1, long x2) { return x1<x2?x1:x2; } long max(long x1, long x2) { return x1>x2?x1:x2; } /* fast solution! */ long maxProduct(long A[], long n) { if(n==1) return A[0]; long min_local = A[0], max_local = A[0], max_global = A[0]; for (long i = 1; i < n; ++i) { long max_local_old = max_local; max_local = max(A[i], max(A[i]*min_local, A[i]*max_local_old)); min_local = min(A[i], min(A[i]*min_local, A[i]*max_local_old)); max_global = max(max_local, max_global); } return max_global; } /* Memory Limit Exceeded */ long maxProduct1(long A[], long n) { if(n==1) return A[0]; long **f = new long *[n]; for(long i=0; i<n; ++i) { f[i] = new long[n]; f[i][i] = A[i]; } long max = A[0]; for(long i=1; i<n; ++i) { for(long j=0; j<n-i; ++j) { f[j][j+i] = f[j][j+i-1]*A[j+i]; if(f[j][j+i]>max) max = f[j][j+i]; } } for(long i=0; i<n; ++i) delete [] f[i]; delete [] f; return max; } }; #define MAX_NUM 10 int main(int argc, char *argv[]) { srand((unsigned)time(NULL)); long n = 100; Solution s; long *A = new long[n]; for(long i=0; i<n; ++i) { A[i] = (rand()%MAX_NUM)-(rand()%MAX_NUM); } clock_t t1 = clock(); long p1 = s.maxProduct(A, n); clock_t t2 = clock(); long p2 = s.maxProduct1(A, n); clock_t t3 = clock(); cout << "algorithm 1 finished in " << 1.0*(t2-t1)/CLOCKS_PER_SEC << " seconds, result: " << p1 << endl; cout << "algorithm 2 finished in " << 1.0*(t3-t2)/CLOCKS_PER_SEC << " seconds, result: " << p2 << endl; delete [] A; return 0; }