连续子数组的最大乘积

  1. 给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合乘积中最大的一组,并写出算法的时间复杂度。(附加:除遍历计数器与a[N] b[N]外,不可使用新的变量,包括栈临时变量、堆空间和全局静态变量等);
  2. 有一个整数数组,求出连续子数组的和的绝对值的最小值。

1、思路:

  先从前往后: B[0]=1, B[1]=A[0], B[2]=A[0]×A[1]...

  再从后往前: temp = 1, temp *= A[n], B[n - 1] *= temp. 就得到除去n-1个数以外,其他数的乘积。

  时间复杂度O(n),空间复杂度O(1),符合题目要求。

 1 int MaxMultiply(const int* A, int len)
 2 {
 3     int* B = new int[len];
 4     B[0] = 1;
 5     for (int i = 1; i < len; i++)
 6         B[i] = B[i - 1] * A[i - 1];
 7     int temp = 1;
 8     for (int j = len - 2; j >= 0; j--)
 9     {
10         temp *= A[j + 1];
11         B[j] *= temp;
12     }
13     int max = 0x80000000;
14     for (int k = 0; k < len; k++)
15         if (B[k] > max) max = B[k];
16     delete[] B;
17     return max;
18 }

  附加:用b[0]来代替temp。第二个循环换成如下:

1 for (i = MAXN - 1; i >= 1; i--)
2 {
3     b[i] *= b[0];
4     b[0] *= a[i];
5 }

 

2、思路:

  对数组A[1...N],做和运算S[1...N],其中S[1] = A[1]; S[2] = A[1]+A[2];...;S[N]=A[1]+A[2]+A[3]+...+A[N]。然后对S[1...N]从小到大排序。最后连续子段绝对值最小:Min{ |S[i+1]-S[i]|} 1<=i<=N。

 

 1 int MinDiffAbs(int data[], int length)
 2 {
 3     int* sums = new int[length];
 4     sums[0] = data[0];
 5     for (int j = 1; j < length; j++)
 6         sums[j] = sums[j - 1] + data[j];
 7     sort(sums, sums + length);
 8     PrintArray(sums, length);
 9     int minDiff = 0x7FFFFFFF, diff;
10     for (int i = length - 1; i > 0; i--)
11     {
12         diff = abs(sums[i - 1] - sums[i]);
13         if (diff < minDiff)
14             minDiff = diff;
15     }
16     delete[] sums;
17     return minDiff;
18 }

 

 

 

posted on 2013-05-26 15:44  月moon鸟  阅读(377)  评论(0编辑  收藏  举报

导航