给定一个长度为N的整数数组,只允许用乘法,不能用除法,计算任意(N-1)个数的组合中乘积最大的一组,并写出算法的时间复杂度。
我们把所有可能的(N-1)个数的组合找出来,分别计算它们的乘积,并比较大小。由于总共有N个(N-1)个数的组合,总的时间复杂度为O(N2),显然这不是最好的解法。
分析与解法
解法一:空间换时间
用s[i]表示数组的前i个元素的乘积,即s[i]=a[0]*a[1]*...*a[i-1]=s[i-1]*a[i-1],边界s[0]=1;
用t[i]表示数组的后N-i个元素的乘积,即t[i]=a[i]*a[i+1]*...*a[N-1]=a[i]*t[i+1],边界t[N]=1;
用p[i]表示数组除第i个元素外,其他N-1个元素的乘积,即有p[i]=s[i-1]*t[i]。
最后求出最大的p[i],时间复杂度为O(N)。
解法二:分析法
假设N个整数乘积为P,则:
(1) P=0
则数组中至少有一个0。假设除去0之后,其他N-1个数的乘积为Q。
若Q=0,则说明数组中至少有两个0,那么N-1个数的乘积只能为0;
若Q>0,则N-1个数的最大乘积为Q;
若Q<0,则N-1个数的最大乘积为0。
(2) P<0
去掉一个负数,即可得到正数。
要使这个正数最大,则去掉绝对值最小的负数即可。
(3) P>0
去掉最小的正数即可。
需要注意的是,直接求N个整数的乘积P,可能会溢出,事实上,我们只需要知道P的正负即可,并不需要得到值。可以通过求出数组中正数、负数和0的个数来判断P的正负性。时间复杂度O(N)。
思考问题
数组乘积问题:输入一个长度为n的整数数组input,输出一个长度为n的整数数组result,满足result=input数组中除了input[i]之外所有的数的乘积(假设不会溢出)。要求:具有线性的复杂度,且不能使用除法运算符。除了result数组外,能否使用O(1)的额外空间来完成这个问题呢?