LeetCode 题解工作台

移山所需的最少秒数

给你一个整数 mountainHeight 表示山的高度。 同时给你一个整数数组 workerTimes ,表示工人们的工作时间(单位: 秒 )。 工人们需要 同时 进行工作以 降低 山的高度。对于工人 i : 山的高度降低 x ,需要花费 workerTimes[i] + workerTimes[…

category

5

题型

code_blocks

8

代码语言

hub

3

相关题

当前训练重点

中等 · 二分·搜索·答案·空间

bolt

答案摘要

我们注意到,如果所有的工人能在 秒内将山的高度降低到 ,那么对于任意 $t' > t$,工人们也能在 秒内将山的高度降低到 。因此,我们可以使用二分查找的方法找到最小的 ,使得工人们能在 秒内将山的高度降低到 。 我们定义一个函数 ,表示工人们能否在 秒内将山的高度降低到 。具体地,我们遍历每一个工人,对于当前工人 ,假设他在 秒内降低了 的高度,那么我们可以得到一个不等式:

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

给你一个整数 mountainHeight 表示山的高度。

同时给你一个整数数组 workerTimes,表示工人们的工作时间(单位:)。

工人们需要 同时 进行工作以 降低 山的高度。对于工人 i :

  • 山的高度降低 x,需要花费 workerTimes[i] + workerTimes[i] * 2 + ... + workerTimes[i] * x 秒。例如:
    • 山的高度降低 1,需要 workerTimes[i] 秒。
    • 山的高度降低 2,需要 workerTimes[i] + workerTimes[i] * 2 秒,依此类推。

返回一个整数,表示工人们使山的高度降低到 0 所需的 最少 秒数。

 

示例 1:

输入: mountainHeight = 4, workerTimes = [2,1,1]

输出: 3

解释:

将山的高度降低到 0 的一种方式是:

  • 工人 0 将高度降低 1,花费 workerTimes[0] = 2 秒。
  • 工人 1 将高度降低 2,花费 workerTimes[1] + workerTimes[1] * 2 = 3 秒。
  • 工人 2 将高度降低 1,花费 workerTimes[2] = 1 秒。

因为工人同时工作,所需的最少时间为 max(2, 3, 1) = 3 秒。

示例 2:

输入: mountainHeight = 10, workerTimes = [3,2,2,4]

输出: 12

解释:

  • 工人 0 将高度降低 2,花费 workerTimes[0] + workerTimes[0] * 2 = 9 秒。
  • 工人 1 将高度降低 3,花费 workerTimes[1] + workerTimes[1] * 2 + workerTimes[1] * 3 = 12 秒。
  • 工人 2 将高度降低 3,花费 workerTimes[2] + workerTimes[2] * 2 + workerTimes[2] * 3 = 12 秒。
  • 工人 3 将高度降低 2,花费 workerTimes[3] + workerTimes[3] * 2 = 12 秒。

所需的最少时间为 max(9, 12, 12, 12) = 12 秒。

示例 3:

输入: mountainHeight = 5, workerTimes = [1]

输出: 15

解释:

这个示例中只有一个工人,所以答案是 workerTimes[0] + workerTimes[0] * 2 + workerTimes[0] * 3 + workerTimes[0] * 4 + workerTimes[0] * 5 = 15 秒。

 

提示:

  • 1 <= mountainHeight <= 105
  • 1 <= workerTimes.length <= 104
  • 1 <= workerTimes[i] <= 106
lightbulb

解题思路

方法一:二分查找

我们注意到,如果所有的工人能在 tt 秒内将山的高度降低到 00,那么对于任意 t>tt' > t,工人们也能在 tt' 秒内将山的高度降低到 00。因此,我们可以使用二分查找的方法找到最小的 tt,使得工人们能在 tt 秒内将山的高度降低到 00

我们定义一个函数 check(t)\textit{check}(t),表示工人们能否在 tt 秒内将山的高度降低到 00。具体地,我们遍历每一个工人,对于当前工人 workerTimes[i]\textit{workerTimes}[i],假设他在 tt 秒内降低了 hh' 的高度,那么我们可以得到一个不等式:

(1+h)h2workerTimes[i]t\left(1 + h'\right) \cdot \frac{h'}{2} \cdot \textit{workerTimes}[i] \leq t

解不等式得到:

h2tworkerTimes[i]+1412h' \leq \left\lfloor \sqrt{\frac{2t}{\textit{workerTimes}[i]} + \frac{1}{4}} - \frac{1}{2} \right\rfloor

我们可以将所有工人的 hh' 相加,得到总共降低的高度 hh,如果 hmountainHeighth \geq \textit{mountainHeight},那么说明工人们能在 tt 秒内将山的高度降低到 00

接下来,我们确定二分查找的左边界 l=1l = 1,由于最少有一个工作,且每个工人的工作时间不超过 10610^6,要想使山的高度降低到 00,最少需要 (1+mountainHeight)mountainHeight/2workerTimes[i]1016(1 + \textit{mountainHeight}) \cdot \textit{mountainHeight} / 2 \cdot \textit{workerTimes}[i] \leq 10^{16} 秒,因此我们可以确定二分查找的右边界 r=1016r = 10^{16}。然后我们不断地将区间 [l,r][l, r] 二分,直到 l=rl = r,此时 ll 即为答案。

时间复杂度 O(n×logM)O(n \times \log M),其中 nn 为工人的数量,而 MM 为二分查找的右边界,本题中 M=1016M = 10^{16}。空间复杂度 O(1)O(1)

1
2
3
4
5
6
7
8
9
10
class Solution:
    def minNumberOfSeconds(self, mountainHeight: int, workerTimes: List[int]) -> int:
        def check(t: int) -> bool:
            h = 0
            for wt in workerTimes:
                h += int(sqrt(2 * t / wt + 1 / 4) - 1 / 2)
            return h >= mountainHeight

        return bisect_left(range(10**16), True, key=check)
speed

复杂度分析

指标
时间complexity is O(n * log(maxTime)) where n is the number of workers and maxTime is the upper bound for binary search. Space complexity is O(1) extra if calculations are done in-place, otherwise O(n) for storing contributions.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Are you thinking about iterating over all possible seconds or can we use a smarter approach?

  • question_mark

    Consider how the workers' different times affect the total reduction and feasibility check.

  • question_mark

    Can you implement a binary search over the valid answer space instead of naive simulation?

warning

常见陷阱

外企场景
  • error

    Assuming sequential work instead of simultaneous worker contributions can overestimate time.

  • error

    Neglecting to check if total units reduced in candidate time meets the mountainHeight.

  • error

    Failing to set a sufficiently large upper bound for binary search may give incorrect results.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Instead of finding minimum seconds, compute the maximum mountainHeight that can be reduced in a fixed number of seconds.

  • arrow_right_alt

    Consider a version where workers have cooldown periods between units of work.

  • arrow_right_alt

    Modify the problem to include varying efficiencies depending on current mountainHeight levels.

help

常见问题

外企场景

移山所需的最少秒数题解:二分·搜索·答案·空间 | LeetCode #3296 中等