给定一个由-1到50个整数组成的列表,范围为-1000到1000,计算给定列表中一个或任意数量的整数的最大乘积。
我的方法:
import itertools
def answer(xs):
cur = 1
dal = []
for i in range(len(xs), 0, -1):
for j in itertools.combinations(xs, i):
for x in j:
cur *= x
dal.append(cur)
cur = 1
dal.sort(reverse=True)
return str(dal[0])
结果超时。我想优化程序的结构,使其尽可能高效。
答案 0 :(得分:2)
除非你有几个月的计算时间,否则完成所有组合是一个坏主意。如果所有数字都是正数,那么你只需要将它们相乘。如果所有这些都是消极的你会采取其中的一些。如果你必须跳过一个,跳过最大值(-2大于-5)。向混合中添加零总是返回零,这比之前的任何情况都要糟糕。如果没有正数且零或一个负数,则只需取最大数字即可。它可以是零或唯一的负数。
def answer(xs):
mult = 1
valid = 0
for i in xs:
if i > 0:
mult *= i
valid = 1
negative = [i for i in xs if i<0]
negative.sort()
if(len(negative) & 1):
del negative[-1]
for i in negative:
mult *= i
valid = 1
if valid==0:
return max(xs)
return mult
以下是一些测试用例:
xs = [0]
print(xs,"->",answer(xs)) #[0] -> 0
xs = [-1]
print(xs,"->",answer(xs)) #[-1] -> -1
xs = [0,-1]
print(xs,"->",answer(xs)) #[0, -1] -> 0
xs = [-2,-3]
print(xs,"->",answer(xs)) #[-2, -3] -> 6
xs = [-2,-3,-4]
print(xs,"->",answer(xs)) #[-2, -3, -4] -> 12
xs = [-2,-3,0]
print(xs,"->",answer(xs)) #[-2, -3, 0] -> 6
xs = [-2,3]
print(xs,"->",answer(xs)) #[-2, 3] -> 3
答案 1 :(得分:0)
如果负数的计数为偶数,则可以通过乘以所有整数来实现最大乘积,否则最大乘积将离开负数(最接近零)并乘以所有其他乘积。 对于n = 1,按原样打印数字。
已编辑:
if len(mylist)==1:
print mylist[0]
else:
count=0
for i in mylist:
if i<0:
count+=1
if count>0:
mylist.sort()
if mylist[-1]==0:
print "0"
else:
ans=1
flag=1
for i in xrange(len(mylist)):
if mylist[i]>0 and flag==1:
ans/=mylist[i-1]
else:
ans*=mylist[i]
if flag==1:
ans/=mylist[-1]
print ans
else:
ans=1
for i in mylist:
if i>0:
ans*=i
print ans
然后从你的函数返回ans。
这是O(n)解决方案。
答案 2 :(得分:0)
这可以通过几种方式进行优化。首先,不是将所有内容托管在数组中,而是将变量maximum
初始化为xs[0]
,并检查每个产品。此外,您可以使用operator
模块中的mul而不是自己进行乘法运算。最后,我会在Python 2中使用xrange
它不会创建一个数组,使其比range
更高效。这将使您的代码看起来像这样
from itertools import combinations
from operator import mul
def answer(xs):
maximum = xs[0]
one = 1 in xs
filter(lambda a: a != 0 and a != 1, xs)
if len(xs) == 0:
if one:
return 1
else:
return 0
for i in xrange(len(xs), 0, -1):
for j in combinations(xs, i):
prod = reduce(mul, j, 1)
if prod > maximum:
maximum = prod
return str(maximum)
我将报告保留为str(maximum)
,但您可以将其作为maximum
返回,如果需要,可以返回整数。
答案 3 :(得分:0)
您可以对 O(n)时间复杂度使用两阶段算法。首先将所有正数相互乘以,如果没有正数,则选择最大数。使用reduce
,可以通过一行轻松完成。
在以下步骤中过滤掉所有负数。如果不止一个将它们全部加在一起。如果乘法结果为负数(=其中有奇数的负数),则将结果除以负数的最大值。然后将步骤1中得到的产品与步骤2的产品相乘,得到最终结果。如果步骤1的产物是非正数,则结果是步骤2的产物。
from functools import reduce
nums = [3, -4, 5, -2, -3, 0, 1]
res = reduce(lambda x,y: x * y if x > 0 and y > 0 else max(x, y), nums)
negatives = [x for x in nums if x < 0]
if len(negatives) > 1:
neg = reduce(lambda x,y: x * y, negatives)
if neg < 0:
neg //= max(negatives)
res = max(res, 1) * neg
print(res)
输出:
180
如果您使用的是Python 2,则无需导入reduce
,因为它是内置的而不是floordiv,只需使用常规的。{/ p>