Python 时间复杂度能从O(n^2)降低到O(n)吗?
我有一个序列A1,A2,A3…一个。对于每个有效的Python 时间复杂度能从O(n^2)降低到O(n)吗?,python,time-complexity,Python,Time Complexity,我有一个序列A1,A2,A3…一个。对于每个有效的i,元素Ai的计数值是有效索引j
i
,元素Ai的计数值
是有效索引j
的数量,使得Aj可被Ai整除
我想知道最大的计数值
我使用了以下代码:
for _ in range(int(input())): #number of test cases
n = int(input()) # no. of elements in A
A = list(map(int, input().split()))
count_arr = [] # array with count value
for i in range(n):
b = A[:i]
b = [x%A[i] for x in b]
count_arr.append(b.count(0))
print(max(count_arr))
样本输入:
1
7
8 1 28 4 2 6 7
样本输出:
3
说明:
A5=2除以4、28和8,因此其计数值为3。那里
count\u arr
中没有具有更高计数值的元素
时间复杂度为O(n2)。我想知道这个问题是否能以更快的方式解决,也许是O(n)复杂度。如果你有一个简单的方法来找出一个数字的除数,你只需要遍历序列一次:
def divisors(num):
yield 1
for i in range (2, int(num ** .5) + 1):
if num % i: # not divisible
continue
yield i
if i**2 != num:
yield num // i
这是一种相当简单的求数字除数的方法
如果还需要包含原始数字,可以将除数更改为
def divisors(num):
yield 1
if num == 1:
return
yield num
for i in range (2, int(num ** .5) + 1):
if num % i: # not divisible
continue
yield i
if i**2 != num:
yield num // i
然后需要一个结构来保存每个除数已经被看到的时间。Acollections.Counter
非常适合此用途
def previous_multiples(sequence):
counter = Counter()
for i in sequence:
yield counter[i]
counter.update(divisors(i))
这就产生了每个数之前的数可以被它整除的数量。然后它用自己的除数更新除数
这可以这样调用max(先前的倍数(序列))
这是在寻找每个数字的除数所需的时间与检查每个元素与之前所有元素所需的时间之间进行权衡。您能否提供一个可复制的示例(包括虚拟数据),以便我们可以从能够实际执行的内容开始工作?是的,它可以在O(n)中求解。请仔细考虑在算法中使用几个变量来存储某些东西,这将有助于您了解最终计数。@smarie Question edited.@AmitUpadhyay如果您能更明确地说明
存储某些东西
,这会有所帮助。我认为如果存在重复项,这种方法可能会失败。如何?你能给出一个反例吗?如果序列[2,4,6,2]
被传递,那么max(先前的倍数(序列))
返回2,应该是3。然后你只需要更改除数
,也包括原始数字。我用fix编辑了我的答案。我做了一些研究,发现了any()
函数。我试图用它来解决这个问题,但结果仍然是时间复杂度为O(n^2)。因此,我似乎应该使用这种方法,直到我找到一些不同的方法。谢谢