我正在尝试确定这两个函数的复杂性,其中整数和列表中的D是整数列表:
def solve(D, list):
for element in List:
doFunc(element, D, list)
def doFunc(element, D, list):
quantityx = 0
if(D > 0):
for otherElement in list:
if otherElement == element:
quantityx += 1
return quantityx + (doFunc ((element+1), (D-1), list))
return 0
直观地说,我认为它有一个O(n²),其中n是列表元素的数量,但我想以正式的方式证明它。
答案 0 :(得分:1)
首先观察:solve
调用doFunc
,但不是相反。因此,solve
的复杂性将取决于doFunc
的复杂性,而不是相反。{我们需要首先弄清楚doFunc
的复杂性。
让T(E, D, N)
成为doFunc
的时间复杂度,E
,D
以及列表中的元素数量N
。每次调用doFunc
时,我们都会对循环执行N
次迭代,然后使用doFunc
,E+1
调用D-1
,并且列表不会更改。基于此,我们知道doFunc
的时间复杂度由以下递归公式给出:
T(E, D, N) = aN + b + T(E+1, D-1, N)
此处,a
和b
是要确定的常量。
现在我们需要这个递归公式的基本案例。我们的基本情况是我们唯一没有递送的时间,就是D <= 0
。假设D
是非负数,这意味着D = 0
是基本情况。我们得到以下额外要求:
T(E, 0, N) = c
在这里,c
是一个常数待定。
综上所述,我们可以为D
的不同值列出一些值,看看我们是否可以识别模式:
D T(E, D, N)
0 c
1 c + b + aN
2 c + 2b + 2aN
3 c + 3b + 3aN
...
k c + kb + kaN
基于此,我们可以猜测T(E, D, N) = c + Db + aDN
对于某些常量a, b, c
。我们可以看到这个公式满足基本情况,我们可以检查它是否也满足递归部分(试试这个)。因此,这是我们的功能。
假设E
,D
和N
都是独立且自由变化的,doFunc
的时间复杂度最好呈现为O(c + Db + aDN) = O(DN)
。
由于solve
为列表中的每个元素调用doFunc
一次,因此其复杂度仅为N
的{{1}}倍,即doFunc
。< / p>