在我的算法和数据结构类中,引入了第一个divide-and-conquer algorithm
即merge sort
。
在实现作业的算法时,我想到了一些问题。
使用分而治之范式实现的算法是否具有O(nlogn)的时间复杂度?
方法中的递归部分是否有能力将运算方式压缩为O(n ^ 2)到O(nlogn)?
是什么让这样的算法首先在O(nlogn)中运行。
对于(3)我假设这与递归树和可能的递归次数有关。有人可能会用一个简单的分而治之算法来运行,该算法在O(nlogn)中运行如何实际计算复杂度?
干杯, 安德鲁
答案 0 :(得分:11)
我认为你问题的所有答案都可能来自Master Theorem它告诉你几乎任何分而治之的解决方案你的复杂性是什么,是的,它必须用递归来做所有事情树,通过玩参数,你会发现一些分而治之的解决方案不会有O(nlogn)的复杂性,实际上有divide and conquer algorithms that have O(n) complexity。
关于问题2,实际上不可能总是存在一些被认为不可能比O(n ^ 2)更快解决的问题,它依赖于问题的本质。
在O(nlogn)中运行的算法示例,我认为它具有非常简单,清晰且有教育意义的运行时分析MergeSort。可以从以下图片中了解:
因此,每个递归步骤将输入分成两部分,然后征服部分采用O(n),因此树的每个级别花费O(n),棘手的部分可能是如何可能的数量递归级别(树高)是登录。这或多或少都很简单。因此,在每个步骤中,我们将输入分成2个n / 2个元素,然后递归重复,直到我们有一些恒定大小的输入。所以在第一级我们除了n / 2,在下一个n / 4,然后是n / 8,直到我们达到一个恒定大小的输入,它将是树的叶子,以及最后一个递归步骤。
所以在第i个递归步骤中我们除了n / 2 ^ i,所以让我们在最后一步找到i的值。我们需要n / 2 ^ i = O(1),这是在2 ^ i = cn时实现的,对于某些常数c,所以我们从两边取基数2的对数并得到i = clogn。因此,最后一个递归步骤将是clogn-th步骤,因此树具有clogn高度。
因此,对于每个clogn递归(树)级别,MergeSort的总成本将为cn,这给出了O(nlogn)复杂度。
一般情况下,只要递归步骤具有O(n)复杂度,并且yo分解为大小为n / b的b问题,或者甚至更一般,您可以确信您的算法将具有O(nlogn)复杂度。如果这些部分是n的线性分数,则加起来为n。在不同的情况下,您很可能会有不同的运行时间。
回到问题2,在QuickSort的情况下,人们可能会从O(n ^ 2)到\ Theta(nlogn),因为平均随机情况实现了一个很好的分区,尽管运行时分析比这更复杂
答案 1 :(得分:8)
不,分而治之并不能保证O(nlogn)的表现。这一切都取决于每次递归时问题的简化。
在合并排序算法中,原始问题分为两半。然后对结果执行O(n)操作。这就是O(n ......)的来源。
现在,这两个子操作中的每一个都有自己的n
,其大小是原始的一半。每次你递归,你再次将问题分成两半。这意味着递归的数量将是log2(n)。这就是O(... logn)的来源。
答案 2 :(得分:5)
使用分而治之范式实现的算法是否具有O(nlogn)的时间复杂度?
平均而言,Quicksort和Mergesort的时间复杂度为O(n log(n)),但并不总是如此。 Big O Cheat Sheet
方法中的递归部分是否有能力将运算方式压缩为O(n ^ 2)到O(nlogn)?
除了眼睛之外,它将取决于其他事物,例如每次递归调用的输入操作数量。
我强烈推荐这个video,你可以看到为什么MergeSort是O(log(n))。
这样的算法首先在O(nlogn)中运行。
同样,这仅仅是指示算法消耗的时间与输入的大小有关,因此说算法的时间复杂度为O(log(n))并不能给出任何关于如何实现算法的信息,它只是说当输入开始增加很多时,使用的时间不会直接增加,而是需要更多的时间和更多。
答案 3 :(得分:2)