【问题标题】:Find the least element in an array, which has a pattern查找数组中具有模式的最小元素
【发布时间】:2011-11-27 02:44:16
【问题描述】:

给定一个数组,使其元素的值从第 0 个索引增加到某个 (k-1) 索引。在 k 处,该值最小,然后通过第 n 个元素再次开始增加。找到最小元素。

本质上,它的一个排序列表附加到另一个;示例:(1, 2, 3, 4, 0, 1, 2, 3)。

我已经尝试过各种算法,例如构建最小堆、快速选择或只是简单的遍历。但不能低于 O(n)。但是这个数组中有一个模式,表明二进制搜索类型的东西应该是可能的,复杂性应该是 O(log n),但找不到任何东西。 想法??

谢谢

【问题讨论】:

  • 你的意思是它减少从0到K吗?
  • 不,它可以从 k 减少到任何值,小于 k 然后再次开始增加。就像我们在一个列表中一个接一个地放置了两个排序的数组,我们需要找到合并点。
  • 考虑到我误解了(显然不是唯一一个),我已经编辑了这个问题以希望澄清。 @JimMischel 得到了清晰的解释。
  • 这些值是一定要加一,还是可以加任意值?

标签: algorithm divide-and-conquer


【解决方案1】:

否 Drop 可以在任何地方,没有结构。

考虑极端情况

1234567890
9012345678
1234056789
1357024689

它简化为寻找最小元素。

【讨论】:

    【解决方案2】:

    对一个递减的范围进行广度二分搜索,在二分分割处有一个元素重叠。换句话说,如果你有 17 个元素,请比较元素

    0,8
    8,16
    0,4
    4,8
    8,12
    12,16
    0,2
    2,4
    

    等,寻找左元素大于右元素的情况。

    一旦找到这样的范围,递归,在该范围内执行相同的二进制搜索。 重复直到找到递减的相邻对。

    平均复杂度不小于O(log n),最坏情况为O(n)。谁能得到更严格的平均复杂度估计?它似乎大致介于 O(log n) 和 O(n) 之间,但我不知道如何评估它。它还取决于对值范围和从一个成员到下一个成员的增量大小的任何附加限制。

    如果元素之间的增量始终为 1,则存在 O(log n) 解。

    【讨论】:

    • 不错!可能具有良好的平均情况行为,但我认为最坏的情况仍然是 O(n)。假设中断看起来像 [... 50, 51, 46, 60, ...]。您只会在最低级别找到它,并且可能会搜索其他所有内容,具体取决于它的位置。我想您可能已经想到了这一点(“它还取决于对值范围和从一个成员到下一个成员的增量大小的任何其他限制。”)
    • @Tom - 谢谢!是的,最坏的情况是 O(n)。在一些限制条件下,可以将测试从“左大于右”更改为更有可能赶上下降的东西。在极端情况下,如果已知数字是连续的,您可以测试右边的数字是否精确地 x 比左边的多,这得到最坏情况 O(log n)。
    【解决方案3】:

    它不能在少于 O(n) 的时间内完成。

    这种最坏的情况会一直困扰着我们——

    越来越多的列表 a1,a2,a3....ak,ak+1... 一个

    只有一个偏差 ak

    所有其他数字都包含关于“k”或“ak”值的绝对零信息

    【讨论】:

      【解决方案4】:

      最简单的解决方案是向前查找列表直到下一个值小于当前值,或者向后查找大于当前值的值。也就是 O(n)。

      同时执行两者仍然是 O(n),但运行时间可能会更快(取决于复杂的处理器/缓存因素)。

      我不认为你可以在算法上比 O(n) 更快地得到它,因为许多分而治之的搜索算法依赖于有一个排序的数据集。

      【讨论】:

        猜你喜欢
        • 2017-01-17
        • 2015-04-18
        • 1970-01-01
        • 1970-01-01
        • 2019-02-24
        • 2013-12-15
        • 1970-01-01
        • 2021-01-13
        • 1970-01-01
        相关资源
        最近更新 更多