最大子序列积

来源:互联网 发布:万方数据库收录期刊 编辑:程序博客网 时间:2024/06/06 18:58

最大子序列积问题

Maximum Product Subarray          2014.10.13      


题目描述来自leetcode题目

寻找一个序列的连续子序列使其乘积达到最大(最少含有一个元素),并返回最大积。

Find the contiguous subarray within an array (containing at least one number) which has the largest product.

例如:

给定序列 [2, 3, -2, 4],连续子序列[2,3] 有最大积等于6.

给定序列 [3, -1, 4],连续子序列[4] 有最大积等于 4.

算法一:


我们知道在求最大子序列和的时候有一种时间复杂度为O(N^3)的方法,即穷举式尝试所有的可能,运行时间O(N^3)由于其效率问题,通常不被采用,为了更好理解这个问题,我们首先给出了这个算法程序

code

/** 最大子序列积 O(N^3) 算法* Cubic maximum contiguous subsequence product algorithm*/int maxSubProduct1(int A[], int n)   // 传入数组地址和元素个数{if( n== 0 )return 0;int maxPro = 1;     // 保存结果for( int i = 0; i < n; i++ ){for( int j = i; j < n; j++ ){int thisPro = 1;      // 保存A[i]*...*A[j]的结果for( int k = i; k <= j; k++ )thisPro *= A[k];if( thisPro > maxPro )maxPro = thisPro;}}return maxPro;}


算法二:


由于我们不需要知道最佳子序列在哪里,因此可以如下改进算法一,改进后的算法时间复杂度为O(N)。

我们知道序列元素A[i]有可能为负,而负负又得正,因此不能只保留A[i]前的最大序列积,还应保留最小序列积。

因此我们定义A[i]前紧邻A[i]的最大序列积为maxPre,A[i]前紧邻A[i]的最小序列积为minPre,A[i]前的最大序列积为maxhere。

我们只需要对数据进行一次扫描,一旦A[i]被处理,它就不再需要被记忆,并完成以下步骤,直到i为n时结束:

  1. maxPre = max(maxPre * A[i], minPre*A[i], A[i]);
  2. minPre = min(maxPre * A[i], minPre*A[i], A[i]);
  3. maxhere = max(maxhere, maxPre);
  • return maxhere.

code

/** 最大子序列积 O(N) 算法* Linear-time maximum contiguous subsequence product algorithm*/int maxSubProduct2(int A[], int n){if (n == 0)return 0;int maxPre = A[0];  // 该元素前相邻子序列最大积int minPre = A[0];  // 该元素前相邻子序列最小积int maxhere = A[0];  // 存储结果int temp;for (int i = 1; i < n; i++){temp = maxPre;     // 先保存下maxPre的值maxPre = max(max(maxPre * A[i], minPre * A[i]), A[i]);minPre = min(min(temp * A[i], minPre * A[i]), A[i]);if(maxPre > maxhere)maxhere = maxPre;}return maxhere;}





做一个对自己有点要求的人。








1 0
原创粉丝点击