代码超时请问在此基础上怎么改

我的一个朋友取从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

可以从两方面优化:

  1. sum(l)被重复了n*n次,其实完全可以放到循环外,只计算1次;
  2. 在内循环中,一旦找到一个j满足条件,或者i*j>sum(l)-i-j,就可以使用break跳出循环,不用再继续循环了。

改成这样就不超时了


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])