【问题标题】:Best way to search for a saturation value in a sorted list在排序列表中搜索饱和值的最佳方法
【发布时间】:2023-03-25 11:17:01
【问题描述】:

来自Math Battle 的问题。 在我的一次工作面试中也有人问过我这个特殊问题。

" 一只猴子有两个椰子。它正在把椰子从阳台上扔下来鬼鬼祟祟 M 层建筑。椰子碎了,猴子想知道最低层。 确定该事实所需的最少尝试次数是多少? "

条件:如果椰子坏了,则不能重复使用。你只剩下另一个椰子了

我能想到的可能的方法/策略是

  • 二元分手&一旦你找到椰子打破的地板,使用从最后找到的二元分手低指数向上计数。
  • 较小的地板组的窗口/切片和在窗口/切片中使用二进制分解 (但不利的一面是,这需要自己的切片算法。)

想知道是否有其他方法可以做到这一点。

【问题讨论】:

    标签: algorithm math search


    【解决方案1】:

    此类面试题旨在了解您的想法。所以我可能会提到上面的 O(N^0.5) 解决方案,但我也会给出以下讨论......

    由于椰子随着时间的推移可能会出现内部开裂,因此结果可能与 O(N^0.5) 解决方案不太一致。尽管 O(N^0.5) 解决方案是有效的,但它并不完全可靠。

    我会推荐第一个椰子的线性 O(N) 解决方案,然后用第二个椰子验证结果。其中 N 是建筑物的楼层数。因此,对于第一个椰子,您可以尝试 1 楼,然后是 2 楼,然后是 3 楼,...

    假设两个椰子的结构完全相同,并且以完全相同的角度掉落,那么您可以将第二个椰子直接扔到第一个弄坏的地板上。称这个椰子破地板 B。

    对于 2 号椰子,您无需在 1..B-1 上进行测试,因为您已经知道第一个椰子在 B-1、B-2、... 1 层没有破裂。所以你只需要在 B 上试一下。

    如果第二个椰子在 B 上断裂,那么您就知道 B 是有问题的地板。如果它没有破裂,您可以推断随着时间的推移椰子内部出现破裂和降解,并且测试开始时存在缺陷。你需要更多的椰子。

    鉴于建筑规模非常有限,对您的解决方案的额外信心值得 O(N) 解决方案。

    正如@Rafał Dowgird 提到的,解决方案还取决于所讨论的猴子是非洲猴子还是欧洲猴子。众所周知,非洲猴子的投掷力要大得多。因此,只有在 +/- 2 层的变化范围内才能使破坏层 B 准确。

    为了保证猴子不会从所有这些楼梯上感到疲倦,建议在第一个椰子上系一根绳子。这样你就不需要为第一个椰子做 1+2+..+B = B*(B+1)/2 楼梯。你只需要做 B 段楼梯。

    似乎楼梯的数量与这个问题无关,但如果猴子一开始就累了,我们可能永远无法解决。这为halting problem 提供了新的考虑因素。

    我们还假设建筑物位于地球上,并且重力设置为 9.8m/s^2。我们还将假设不存在引力波。

    【讨论】:

    • +1 用于讨论椰子不均匀性。我也不会错过讲一些 Monthy Python 笑话的机会(“非洲猴子还是欧洲猴子?”)。
    • 感谢您的解释.. 喜欢细节.. 椰子不均匀,非洲与欧洲猴子,悬挂绳和停止问题.. 很好的答案..!!
    【解决方案2】:

    二分查找不是答案,因为你只有一次机会高估。二分搜索需要log m 最大高估。

    这是一个两阶段的方法。第一个是用相对大的步骤迭代楼层。在第一个椰子破后,第二阶段是从最后一个安全层开始尝试每一层。

    大步大致为sqrt(m),但它们在早期较大,而在后期较小,因为如果第一个椰子提前破裂,您可以在第二阶段进行更多迭代。

    StepSize = (minimum s such that s * (s + 1) / 2 >= m)
    CurrentFloor = 0
    
    While no coconuts broken {
        CurrentFloor += StepSize
        StepSize -= 1
    
        Drop coconut from CurrentFloor
    }
    
    CurrentFloor -= StepSize + 1
    
    While one remains coconut unbroken {
        CurrentFloor += 1
        Drop remaining coconut from CurrentFloor
    }
    
    // CurrentFloor is now set to the lowest floor that will break the coconut, 
    // using no more total drops than the original value of StepSize
    

    【讨论】:

      【解决方案3】:

      我知道的最佳解决方案是 2*sqrt(n)。将第一个椰子从 sqrt(n), 2*sqrt(n),... 放到 n (或直到它破裂)。然后从最后一个已知的“安全”点放下第二个,以一层为增量,直到它破裂。两个阶段最多进行 sqrt(n) 次抛出。

      编辑:您可以改进 O(sqrt(n)) 内的常数,请参阅递归注释。我认为第一步应该在 sqrt(2*n) 左右,每次投掷减 1,这样最后一步(如果断裂高度实际上是 n)正好是 1。细节有待读者了解 :)

      【讨论】:

        【解决方案4】:

        既然是面试题,就考虑

        1. 昂贵的操作是猴子上下楼梯,而不是折腾椰子。这么一想,‘线性’的方式其实是N2

        2. 落下时传递给椰子的能量大致与落下的高度成正比。如果外壳在所有下落中吸收了一些能量后破裂......

        【讨论】:

        • 令我惊讶的是,有多少人直接进入他们认为包含在其中的编程问题,而不考虑包装器的有趣属性。
        【解决方案5】:

        棘手的面试问题。我花了几天时间。

        我相信尝试次数是楼层数 SQRT 的 1.5 倍。 (对于 100 层和 2 个 coco 是 15)

        我们希望尽量减少每次尝试的大小和尝试次数,同时使用两者来覆盖所有可能的楼层。在这种情况下,sqroot 被证明是一个很好的起点,但我们会改变每次尝试的大小和围绕 sqroot 的平均值。 这样我们就拥有了两全其美的优势:每次尝试的大小均匀分布在 sqroot 周围会给我们最好的结果。对于 100 和 2,这是 15、14、13、12、11、10、9、8、7、6 这相当于 10 的 1.5 倍。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-28
          • 1970-01-01
          • 1970-01-01
          • 2010-10-27
          • 1970-01-01
          • 1970-01-01
          • 2020-03-27
          • 1970-01-01
          相关资源
          最近更新 更多