我有这个算法,我正试图计算它的复杂性。
A = {a_1, a_2, a_3, ...}
w = 0
while A != empty
a' = argmin(A) #a' is the element with smallest y_a
if (N_a' + w > C)
A = A - {a'}
else
x_a' = x_a' + 1
w = w + N_a'
Update the y_a' value in A using x_a'
A
是一个集合,如果条件(N_a' + w > C
)是 true ,我们会从集合中删除一个元素,直到该集合为空。我知道该算法至少运行O(n)
,但如果if
语句 false ,它可以运行更多。假设最后一行(更新)需要一个恒定的时间。
我如何计算这里的复杂性?
答案 0 :(得分:1)
让我们首先确定then和else分支在最坏的情况下运行的频率。在then分支中,集合A变小一个元素,因此它只能执行n次(其中n是A中元素的初始数量)。 else分支最多可以执行C次(取N_a'= 1,它必须> = 1)。 C是常数,因此这是O(1)。因此,迭代总数为O(n)。
关键点现在是用于A的数据结构。必须支持三个操作:查找min,删除最小元素,以及最后一行中的更新。当我们选择最小堆时,每个操作都可以在O(log n)中完成。请注意,在这种情况下,更新不 O(1)时间。总运行时间现在为O(n log n)。
朴素的最小搜索(即,使用A的无序数组)使操作分钟,删除元素,并分别更新O(n),O(1)和O(1)。因此总运行时间为O(n * n)。
使用有序数组表示A,我们分别得到O(1),O(1)和O(n)的运行时间。每次迭代执行最小搜索O(1)操作,因此O(n)次。 remove elemnt O(1)操作在then分支中,因此执行O(n)次,更新O(n)操作在else分支中,因此执行O(1)次。综合考虑,给出了O(n)的运行时间。 但是,如果必须在开头对集合进行排序,我们再次处于O(n log n)。