您的位置:首页 > 职场人生

微软面试题---求子数组最大乘积问题

2010-10-03 15:39 573 查看
最近从网上看到一个讨论较多的题目:

“ 给定一个长度为N的整数数组,只允许用乘法,计算任意(N-1)个数的组合乘

积中最大的一组,并写出算法的时间复杂度。

分析:

(1) 按题目的要求,是求去掉一个元素后,剩下元素的乘积最大的那种组合。

(2) 整数数组,其元素可能取值为 : 正整数、负整数,和零。

(3) 设数组中有 p个零, q 个 负数, r 个正数

a ) 若 p>=2 则,

任意 (N-1)个数的组合之积均为 0. 所以答案是:任意去除一个元素即可。

b ) 若 p = 1 ( 原数组中含 一个 0 )

若 q 为偶数 , 则 去掉 为0的元素即可

若 q 为奇数, 则 去掉任意一个负数均可,

乘积为0,是最大的,其他任意组合均小于0。

c ) 当 p = 0时( 原数组中不含 “零” )

当 q = 0 时 ( 不含负数时 )

去掉值最小的元素即可

当 q 为奇数 时,

去掉绝对值最小的负数元素 即可

否则:( 有偶数个负数 )

如果 r >0 ( 即原数组中至少有一个正数 ):

去掉值最小的正数元素 即可

否则 ( 一个正数也没有, 也没有 0 ,全是负数 )

去掉绝对值最大的负数元素即可。

根据这个分析,程序不难设计出来。

讨论 :

原题有“只允许用乘法”字样,不知是什么意思? 因为本算法中没有用到乘法,不知道,比较运算符是否允许使用? 本算法中,计算正数、负数、零的个数时,需用“加法”,如果不能用,就是原出题人思路有问题。

#coding=gbk
# 给定一个长度为N的整数数组, 计算任意(N-1)个数的组合
# 乘积中最大的一组,并写出算法的时间复杂度

def max_mult( A ):
p = 0 # 数组中 零的个数
q = 0 # 数组中 负数的个数
r = 0 # 数组中 正数的个数
pos_0 = -1 # 首次 “0” 出现的位置
pos_max_fu = -1 # 绝对值最大的负数所在的位置
pos_min_fu = -1 # 绝对值最小的负数所在的位置
pos_min_zhen = -1 # 最小正数 的位置
for i in range(0,len(A)):
x = A[ i ]
if x == 0:
p = p +1
if pos_0 == -1:
pos_0 = i
elif x<0:
q = q +1
if q==1:
pos_max_fu,pos_min_fu = i,i
else:
if -x > -A[ pos_max_fu ] :
pos_max_fu = i
elif -x < -A[ pos_min_fu ] :
pos_min_fu = i
else:
r = r +1
if r==1:
pos_min_zhen = i
elif x < A[ pos_min_zhen ]:
pos_min_zhen = i
if p>=2:
return A[0:pos_0]+A[pos_0+1:]
if p==1:
if (q % 2)==0:
return A[0:pos_0]+A[pos_0+1:]
return A[0:pos_min_fu]+A[pos_min_fu+1:]
if q==0:
return A[0:pos_min_zhen]+A[pos_min_zhen+1:]
if (q%2) == 1:
return A[0:pos_min_fu]+A[pos_min_fu+1:]
if r>0:
return A[0:pos_min_zhen]+A[pos_min_zhen+1:]
return A[0:pos_max_fu]+A[pos_max_fu+1:]


a = [ 0,0,4,1,5]
print( a, max_mult(a) )
a = [ 0,1,4,1,5]
print( a, max_mult(a) )
a = [ 0,-1,4,1,5]
print( a, max_mult(a) )
a = [ 0,-1,4,-3,5,-8]
print( a, max_mult(a) )


a = [ 0,-5,4,-1,5]
print( a, max_mult(a) )


a = [ 2,-3,4,-1,5,-8]
print( a, max_mult(a) )
a = [ -3,4,-1,-5,-8,2]
print( a, max_mult(a) )
a = [ -3,-4,-1,-5 ]
print( a, max_mult(a) )


a = [ -3,-4,-1,-5 ,-7]
print( a, max_mult(a) )


结果:(为了便于观察结果是确,我们下面的结果中,左侧是原数组,右侧是求出的数组:)

[0, 0, 4, 1, 5] [0, 4, 1, 5]
[0, 1, 4, 1, 5] [1, 4, 1, 5]
[0, -1, 4, 1, 5] [0, 4, 1, 5]
[0, -1, 4, -3, 5, -8] [0, 4, -3, 5, -8]
[0, -5, 4, -1, 5] [-5, 4, -1, 5]
[2, -3, 4, -1, 5, -8] [2, -3, 4, 5, -8]
[-3, 4, -1, -5, -8, 2] [-3, 4, -1, -5, -8]
[-3, -4, -1, -5] [-3, -4, -1]
[-3, -4, -1, -5, -7] [-3, -4, -5, -7]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: