我无法理解复杂性分析中log(k)和log(n)之间的区别。
我有一个大小为n的数组。我有另一个数字k< n是算法的输入(所以它不是提前知道的常数)。有哪些算法的例子有log(n)和log(k)的复杂性?我只能想到在复杂性上有log(n)的算法。
例如,mergesort在运行时分析中具有log(n)复杂度(O(nlogn))。
答案 0 :(得分:0)
如果您的算法采用大小为n
且幅度为k < n
的列表,则输入大小为n + log(k)
(假设k可能位于相同的渐近顺序) n
)。为什么? k
是在地方价值系统中表示的数字(例如,二进制或十进制),数量k
需要log k
个数字来表示。
因此,如果您的算法采用输入k
并以需要使用或检查所有数字的方式使用它(例如,正在检查相等性等),则整个算法的复杂性为至少在log k
的顺序。如果你用数字做更复杂的事情,复杂性可能会更高。例如,如果你有类似for i = 1 to k do ...
的内容,那么算法的复杂性至少为k
- 可能更高,因为你要比较log k
- 位数{{ 1}}次(尽管k
对i
的多个/大多数值使用的位数少于k
,具体取决于基数)。
答案 1 :(得分:0)
没有&#34;一刀切的&#34;解释O(log k)术语可能出现在哪里。
有时您会发现此运行时出现在搜索和排序算法中,您只需要重新排列序列的一小部分。例如,C ++标准库的std::partial_sort
函数,它重新排列序列,使得前k个元素按排序顺序,其余的按时间任意顺序为O(n log k)。可以实现的一种方法是保持最小大小为k的最小堆并对其进行n次插入/删除,这是n个操作,每个操作花费时间O(log k)。类似地,有一个O(n log k)时间算法用于查找数据流中的k个最大元素,它通过维持最多k个元素的最大堆来工作。
(这些方法都不是最佳的 - 你可以使用线性时间选择算法对时间O(n + k log k)进行部分排序,并且可以类似地在O中找到数据流的前k个元素(n)中。)M
您有时也会在算法中看到此运行时涉及一种分而治之的策略,其中所讨论问题的大小取决于输入大小的某些参数。例如,用于计算凸包的Kirkpatrick-Seidel algorithm在重复中每个级别进行线性工作,并且层数是O(log k),其中k是得到的凸包中的元素数。然后总工作为O(n log k),使其成为输出敏感算法。
在某些情况下,可能会出现O(log k)项,因为您一次处理一个数字的元素集合。例如,radix sort在用于排序范围从0到k(包括0和k)的n个值时具有O(n log k)的运行时间,其中log k term来自O(log k)的事实数字k中的数字。
在图算法中,边数(m)与节点数(n)有关但可以独立于节点数(n),你经常会看到像O(m log n)这样的运行时,就像你{ {3}}