【问题标题】:Increasing algorithm efficiency using divide and conquer paradigm使用分而治之的范式提高算法效率
【发布时间】:2018-02-22 17:36:40
【问题描述】:

我想找到一个数组中的最小和最大整数。我相对低效的方法是考虑第一个整数到最大值\最小值。然后我将其与其他整数进行比较,如果将更大/更小的整数与当前的最小或最大整数进行比较,则将其替换。这一直持续到数组结束。根据我的计算,复杂性(基于最坏的情况)是 n -1 (n 是数组的大小)。我的问题是如何使用分而治之的范式来提高效率?我尝试将数组分成两部分,然后对两个部分执行与上述相同的算法,尽管这只会降低效率?根据我的计算,复杂度变为 n + 1。

【问题讨论】:

  • 在您的情况下,如果像您已经想到的那样,将数组分成块并设置 几个线程,每个块一个线程,那么 D&C 会更有效。收集线程的结果并使用这个减小了大小的数组重复。
  • 您需要检查数组中的 每个 数字,因此它将是 O(n)
  • blueCat 我使用比较操作来测量复杂度,在最坏的情况下会达到 n - 1?
  • O(n) 或 O(n-1) 没有任何真正的区别;它们都意味着复杂性是线性的,即如果您将输入加倍,它将使处理该输入所需的步骤数加倍。找到无序列表的最大值永远不会低于 O(n) 复杂度,但您当然可以使用 D&C 来为其投入更多处理器,正如 Ripi2 所提到的,并实际提高速度。
  • 无论是 n-1 还是 n+1,复杂度都是 O(n),因为 O(n)、O(n+1) 和 O(n-1)(以及 O(n /2) FWIW) 从字面上看都是一样的What is a plain English explanation of “Big O” notation? 但是,您可以查看实际的比较次数(对于寻找最小值和最大值的幼稚实现,这将接近 2n),例如,如果您愿意(并忽略复杂性)。

标签: algorithm search time-complexity divide-and-conquer


【解决方案1】:

我会认为你正在使用一个线程

如果数组未排序,复杂度将始终为O(n)。但是,在我看来,您应该检查您是否只需要最大数量?或者第二个最大值,以及第三个最大值..

如果是这种情况,您最好构建一个最大堆(对应情况的最小堆),这需要 O(nlogn) 时间,然后只需检查堆的 peek。

【讨论】:

    【解决方案2】:

    为了识别n 元素的最大值,算法必须从比较中获得足够的信息。假设最大值为array[i],您必须将array[i]array[0], ... array[i-1], array[i+1], ... array[n-1] 进行比较,以证明array[i] 是最大值。所以所需的最小比较次数是n - 1比较,以便找到最大值。为什么?因为数组中有n 元素,算法必须从比较中获得足够的信息才能找到最大值。


    Python 中的示例代码

    # Divide-and-Conquer find max of alist
    def dc_max(alist, start, end): # first call with start=0, end=len(alist)
        if end - start == 1: # base case: list of 1 element
            return alist[start]
        mid = (start + end) // 2
        x = dc_max(alist, start, mid)
        y = dc_max(alist, mid, end)
        if x > y:
            return x
        return y
    
    # Iterative find max of alist
    def it_max(alist):
        current = alist[0]
        for i in range(1, len(alist)):
            if i > current:
                current = i
        return current
    

    两种算法都精确地进行n - 1 比较并且是就地的,因此它们都具有Θ(n) 时间复杂度和O(1) 空间复杂度。


    性能现在取决于您的系统。见Is recursion ever faster than looping?

    在我的例子中,使用递归方法查找 2**20 数字列表的最大值需要 657ms,而使用迭代方法需要 111ms

    【讨论】:

      猜你喜欢
      • 2020-07-17
      • 2013-02-02
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      • 2013-02-03
      • 2017-06-08
      • 1970-01-01
      • 2020-04-21
      相关资源
      最近更新 更多