问题描述
我正在解决一些与找到算法时间复杂度有关的问题,并遇到了这个问题。这让我很难理解该函数的时间复杂度。该代码段的图像如下所示。有人可以帮我理解一下,并向我介绍如何解决这些类型的问题吗?提前非常感谢!
PS-请不要将此问题标记为重复!
解决方法
简单的情况:假设数组仅包含不同的元素
由于这一假设,最后一行return search...() + 1 + search...()
在执行期间最多可以执行一次。
因此,在每个递归调用中,数组中搜索区域的大小都除以2(并减去1);除了最多有两次递归调用而不是仅1.之外。
当搜索区域达到大小0时,执行结束。
最初,搜索区域的大小为N
:它是整个数组。
在N
除以2
到值1
之前,我们可以除以多少次,然后再乘以1,再除以0?
这个问题是众所周知的,因为它在算法中经常发生。答案是大约log2(N)
。
因此最多将有log2(N)
个递归调用,除非一次执行可能会拆分为递归调用;因此,将在log2(N)
和2 log2(N)
之间进行递归调用。每个递归调用都是固定时间的;因此执行的总时间为Θ(log(N))
。
简并的情况:所有元素都等于k
在这种情况下,两个if
条件V[mid] </> k
都不是真实的;因此,我们总是会遇到第一种情况(return 0
)或最后一种情况(return ... + 1 + ...
)。
在这种情况下,该函数的最终返回值为N
,因为该函数正在计算数组中k
的出现次数。由于返回值仅由+1+
构建,因此必须有精确的N
调用,每个调用都贡献+1+
;在触发的两个递归调用中,最多两个立即返回0;因此,递归调用的总数必须至少为N
,并且最多为3*N
。因此,复杂度为Θ(N)
。
“一般”案件
数组中k
的出现可能不止1次。出于与上述相同的原因,算法的复杂度应为Θ(K + log(N))
,其中K
是K
的出现次数,而N
是数组的大小。最好的情况是Θ(log(N))
,最坏的情况是Θ(N)
。总结为O(N)
。
平均复杂度
如果我们假设输入数组是按照已知的概率分布随机生成的,则可以计算复杂度的期望值。通常将其称为“平均复杂度”。精确地计算将非常困难,在这种情况下,假设中的概率分布似乎起着巨大的作用,因此不同的分布将导致不同的平均复杂度。例如,如果数组中填充有N个独立且均匀地随机分布的数字,则范围为[0,10 ^ N],则k
在数组中多次出现的概率非常低,因此我猜在这种情况下,预期的复杂度将接近log(N)
。但是,如果N
个数字是在[0,10]范围内随机抽取的,那么您可以期望数字的十分之一等于k
,因此平均复杂度将接近{ {1}}。
通常为算法 Quicksort 计算一个“平均复杂度”,假设一个列表随机地均匀地随机排列。 Quicksort最坏情况下的复杂度是Θ(N);其最佳情况下的复杂度为Θ(log(N))。假设一个列表随机地随机混洗,其平均复杂度为Θ(log(N))。许多计算机科学教科书都对此进行了“证明”。但是,到目前为止,我所读过的所有有关该主题的教科书在某些时候还是有些手摇的。我还没有发现一本书能以一种真正令人信服的方式来处理证明,而书中所希望的是从数学证明中得到的严谨。