我的一个朋友取从1到n的所有数字的序列(其中n>0)。
在这个序列中,他选择了两个数字,a和b。
他说a和b的乘积应该等于序列中所有数字的和,不包括a和b。
给定一个数字n,你能告诉我他从序列中排除的数字吗?
该函数接受参数:n(n始终严格大于0),
并返回一个数组或字符串(取决于语言),格式为:[(a,b),…]
将按“a”的递增顺序排序。碰巧有几种可能的(a,b)?
如果找不到可能的数字,函数将返回一个空数组(或空字符串),
这将证明我的朋友没有说实话!
题如上,代码没错但是限制了时间,有些值会超时,请问怎么改
def remov_nb(n):
res = []
l = [x for x in range(1, n + 1)]
s = sum(l)
for i in l:
for j in l:
if i * j == s - i - j:
res.append((i,j))
break
return res
print(remov_nb(26))
我想问的是,超时的时候,你的n有多大?但你没有明白我的意思。不过,这不是重点,重点是这样简单的算法,不应该如此耗时。我简单写了一个算法,令n从1000到1100,其中有20个数形成的序列可以找到符合条件的a和b,每一个查找,都没有超过1毫秒。
>>> import time
>>> def remov_nb(n):
s = sum(range(1, n+1))
p, q = int((s-n)/(n+1)), n
res = list()
while p <= q:
if p*q == s-p-q:
res.append((p,q))
p += 1
q -= 1
elif p*q > s-p-q:
q -= 1
else:
p += 1
return sorted(res, key=lambda x:x[0])
>>> for i in range(1000, 1100):
t0 = time.time()
result = remov_nb(i)
t1 = time.time()
if result:
print(i, result, '%0.3f'%(t1-t0))
1006 [(546, 925)] 0.001
1011 [(682, 748)] 0.000
1016 [(700, 736)] 0.001
1018 [(615, 841)] 0.000
1025 [(528, 993)] 0.001
1034 [(633, 843)] 0.001
1035 [(540, 990)] 0.000
1037 [(682, 787)] 0.000
1039 [(552, 976)] 0.001
1044 [(640, 850)] 0.000
1050 [(687, 801)] 0.001
1052 [(672, 822)] 0.001
1060 [(736, 762)] 0.001
1068 [(598, 952)] 0.000
1074 [(741, 777)] 0.001
1077 [(595, 973)] 0.001
1086 [(700, 841)] 0.001
1090 [(561, 1057)] 0.001
1093 [(631, 945), (687, 868)] 0.000
1094 [(666, 897)] 0.001
可以从两方面优化:
改成这样就不超时了
def remov_nb(n):
s = sum(range(1,n+1))
p,q = int((s-n)/(n+1)),n
res = list()
while p < q:
if p*q == s-p-q:
res.append((p,q))
res.append((q,p))
p+=1
q-=1
elif p*q > s-p-q:
q -= 1
else:
p+=1
return sorted(res,key = lambda x:x[0])