【问题标题】:Complexity of the following algorithm to find minimum value in an unsorted array以下算法在未排序数组中找到最小值的复杂性
【发布时间】:2019-04-06 22:47:26
【问题描述】:

通过使用分治法,如果我们将一个数组重复分成两半,直到它们减小到两个大小 - 之后我们可以在 O(1) 时间内返回两者中的最小值。扩展该方法,为了将两个子数组 A 和 B 分别与它们的最小值 'a' 和 'b' 合并,我们可以在 O(1) 时间内直接返回它们的最小值——使合并步骤成为一个恒定时间操作。

这实质上意味着存在 logN 个级别,合并步骤的复杂度为 O(1)。那么这是否意味着使用该算法在未排序数组中找到最小值的复杂度为 O(logN)?

另外,请参阅此讨论。

Finding the minimum in an unsorted array in logarithmic time

【问题讨论】:

  • 递归树 分支 乘以 2。您将拥有指数级的子数组。

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


【解决方案1】:

甚至不看你的算法,O(Log N) 就永远不可能找到最小值。

因为无论采用何种策略,在您看到所有元素之前都无法知道最小值。 (在未排序的数组中,读取一个元素绝对不会提供其他元素的信息。)

因此寻找最小值是一个 Ω(N) 问题。

【讨论】:

    【解决方案2】:

    之后我们可以在 O(1) 时间内返回两者中的最小值。

    您确实在恒定时间内比较了一对值,但您有 n/2 对值要比较。这使得第一步总共为 O(n/2)(这已经是 O(n)),并且总结每一步得到 O(n/2 + n/4 + n/8 + ...)。

    简而言之,您仍然需要进行至少 n-1 次比较。没有任何漏洞。

    【讨论】:

      【解决方案3】:

      虽然 Nelfeal Yves Daoust 回答得很好,但我想补充一些评论。

      只有未排序的数组,没有其他方法可以在亚线性时间内找到最小值/最大值。由于我们不知道哪个元素最大或最小,因此您必须全部查看。

      实际改进

      如果我们在数据结构上允许更多的操作和空间,我们可以让它更快。

      • 数组为空

        • Insert(e):使用 e 的值设置最小值/最大值。 O(1)
        • Remove(e):返回一些预定义的值。 O(1)
        • Minimum/Maximum(e):返回一些预定义的值。 O(1)
      • 数组非空

        • Insert(e):将 e 的值与最小值/最大值进行比较。如果满足条件,则使用 e 的值设置最小值/最大值。 O(1)
        • Remove(e) : 如果最小值/最大值 == e ,则将最小值/最大值设置为未知(可能为 NULL?)。否则,只需从数组中删除 e 。 O(1)
        • Minimum/Maximum(e) :如果最小值/最大值未知,则使用 O(N) 算法查找并设置最小值/最大值。如果已知最小值/最大值,则返回它。 O(N) 或 O(1)。

      优点和缺点

      插入/删除和最小/最大之间的操作比率决定了该算法的性能。 如果最小/最大操作的数量大于插入/删除,从概率上讲,随着数组变得越来越大,该算法的工作速度更快。

      【讨论】:

      • 您正在尝试解决一个不同的问题,即最小/最大值的动态维护。 Remove(e) 可以在 O(1) 时间内完成是错误的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 2019-03-31
      • 2012-01-12
      • 2021-12-16
      • 2011-07-22
      • 2021-11-21
      • 1970-01-01
      相关资源
      最近更新 更多