【发布时间】:2022-01-21 14:35:26
【问题描述】:
我正在尝试分析此algorithm 的最坏情况空间复杂度以解决Codility's CountNonDivisible problem。
问题陈述:
给定一个由 N 个整数组成的数组 A。
对于每个满足 0 ≤ i
写一个函数,给定这样一个数组,返回一个序列 表示每个元素的非除数数量的整数。
为以下假设编写一个高效算法:
- N 是 [1, 50,000] 范围内的整数
- 数组 A 的每个元素都是 [1, 2N] 范围内的整数。
算法(我添加了cmets):
def solution(A):
A_max = max(A) # O(1) space
count = {} # O(1) space
# Create a count of the occurrences of each element in the input array.
# O(N) space
for element in A:
if element not in count:
count[element] = 1
else:
count[element] += 1
divisors = {} # O(1) space
# O(N) space
for element in A:
divisors[element] = set([1, element])
divisor = 2 # O(1) space
# Space TBC
while divisor*divisor <= A_max:
element_candidate = divisor # O(1) space
while element_candidate <= A_max: # O(1) space
if element_candidate in divisors and not divisor in divisors[element_candidate]: # O(1) space
divisors[element_candidate].add(divisor) # O(1) space
divisors[element_candidate].add(element_candidate//divisor) # O(1) space
element_candidate += divisor # O(1) space
divisor += 1 # O(1) space
result = [0] * len(A) # O(N) space
# Space TBC
for idx, element in enumerate(A):
result[idx] = (len(A) - sum([count.get(divisor,0) for divisor in divisors[element]]))
return result
article 指出预期的最坏情况空间复杂度为 O(N)。
但是divisors dict 需要空间来存储它存储的除数集。
如果 dict 中的每个值都是整数,我就会清楚为什么最坏情况下的空间复杂度是 O(N)。但是每个值都是一组整数。
所以我认为除数集所需的总空间与除数的总数成正比。
在最坏的情况下,所有这些集合中大约会存储多少个除数?
最坏的情况应该发生在,对于给定的 N,我们最大化存储在所有集合中的除数总数。
为此,我认为我们可以使用以下算法:
- 构造一个大小为 2N 的数组 B,其元素等于 d(n) sequence 中的前 2N 个值 - 即列出 n 的除数的序列。 (我们取 2N 个值,因为 CountNonDivisible 问题的输入数组中任何元素的最大值为 2N。)令 Bi 为 B 的索引数组。
- 对 B 和 Bi 的元素进行排序,首先按 B 中的值(按降序),然后按 Bi 中的值(也按降序) )。
- 然后让最坏情况输入数组 A 为由 Bi 中的前 N 个元素组成的子数组。
例如,如果 N = 12,则 2N = 24,并且在排序之前:
Bi = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19、20、21、22、23、24]
B = [1, 2, 2, 3, 2, 4, 2, 4, 3, 4, 2, 6, 2, 4, 4, 5, 2, 6, 2, 6, 4, 4, 2、8]
排序后:
Bi = [24, 20, 18, 12, 16, 22, 21, 15, 14, 10, 8, 6, 9, 4, 23, 19, 17, 13, 11、7、5、3、2、1]
B = [8, 6, 6, 6, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1]
而输入数组 A = [24, 20, 18, 12, 16, 22, 21, 15, 14, 10, 8, 6]
除数总数为 59。
我正在努力解决的是如何对 [1, 50,000] 范围内的任何 N 进行概括。
我假设 Codility 在某处陈述/证明了 O(N) 最坏情况的空间复杂度,但我无法找到在哪里。
我上面的分析是否正确?如果是这样,我将如何完成最坏情况空间复杂度的计算?
如果不是,那么实际上是 O(N) 吗?如果是 O(N),我在分析中做错了什么?
【问题讨论】:
标签: python algorithm big-o space-complexity