为什么分而治之的算法通常比蛮力运行得更快?

时间:2012-06-15 00:37:22

标签: algorithm complexity-theory brute-force divide-and-conquer

为什么分而治之算法通常比蛮力更快?例如,找到最接近的一对点。我知道你可以告诉我数学证明。但直觉上,为什么会这样呢?魔法?

理论上,“分而治之总是比蛮力更好”是真的吗?如果不是,是否有任何反例?

2 个答案:

答案 0 :(得分:18)

对于你的第一个问题,分而治之的直觉是,在许多问题中,必须完成的工作量是基于输入的一些组合属性,这些属性比线性扩展更多。

例如,在最接近的点对问题中,蛮力答案的运行时间取决于您必须查看所有O(n 2 )可能的点对的事实

如果你采取了一些平方增长的东西并将其切割成两块,每块都是以前的一半,那么每半年需要四分之一的时间才能解决问题,所以解决了两半的问题花费时间大约是蛮力解决方案所需时间的一半。将其分成四块将花费四分之一的时间,将其分成八块,八分之一,等等。

递归版本在这种情况下最终会变得更快,因为在每一步中,我们通过确保实际上不需要检查太多的对来避免通过处理元素对做很多工作。由于类似的原因,大多数具有分而治之解决方案的算法最终会更快。

对于你的第二个问题,不,分而治之算法不一定比蛮力算法更快。考虑在数组中找到最大值的问题。蛮力算法需要O(n)时间并使用O(1)空间,因为它对数据进行线性扫描。这里给出了分而治之的算法:

  • 如果数组只有一个元素,那就是最大值。
  • 否则:
    • 将阵列切成两半。
    • 找出每一半的最大值。
    • 计算这两个值的最大值。

这也需要时间O(n),但是使用O(log n)内存作为堆栈空间。它实际上比简单的线性算法更差。

另一个例子是maximum single-sell profit problem有一个分而治之的解决方案,但优化的动态编程解决方案在时间和内存上都更快。

希望这有帮助!

答案 1 :(得分:3)

我建议你仔细阅读算法设计的第5章,它很好地解释了分而治之。

直观地说,对于一个问题,如果你可以把它分成两个与原点相同的子问题,将两个子问题的结果合并到最终结果的时间复杂度有点小,然后它比通过蛮力解决原始完整问题更快。

正如在算法设计中所说的那样,你实际上无法从时间上分而治之地获得太多,一般来说你只能将时间复杂度从更高的多项式降低到更低的多项式(例如从O (n ^ 3)到O(n ^ 2)),但很难从指数到多项式(例如从O(2 ^ n)到O(n ^ 3))。

我认为你从分而治之中获得的最大收获是解决问题的心态。将原始的大问题分解为更小更容易的子问题总是一个很好的尝试。即使你没有更好的运行时间,它仍然可以帮助你思考问题。