LeetCode 题解工作台
移山所需的最少秒数
给你一个整数 mountainHeight 表示山的高度。 同时给你一个整数数组 workerTimes ,表示工人们的工作时间(单位: 秒 )。 工人们需要 同时 进行工作以 降低 山的高度。对于工人 i : 山的高度降低 x ,需要花费 workerTimes[i] + workerTimes[…
5
题型
8
代码语言
3
相关题
当前训练重点
中等 · 二分·搜索·答案·空间
答案摘要
我们注意到,如果所有的工人能在 秒内将山的高度降低到 ,那么对于任意 $t' > t$,工人们也能在 秒内将山的高度降低到 。因此,我们可以使用二分查找的方法找到最小的 ,使得工人们能在 秒内将山的高度降低到 。 我们定义一个函数 ,表示工人们能否在 秒内将山的高度降低到 。具体地,我们遍历每一个工人,对于当前工人 ,假设他在 秒内降低了 的高度,那么我们可以得到一个不等式:
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 二分·搜索·答案·空间 题型思路
题目描述
给你一个整数 mountainHeight 表示山的高度。
同时给你一个整数数组 workerTimes,表示工人们的工作时间(单位:秒)。
工人们需要 同时 进行工作以 降低 山的高度。对于工人 i :
- 山的高度降低
x,需要花费workerTimes[i] + workerTimes[i] * 2 + ... + workerTimes[i] * x秒。例如:- 山的高度降低 1,需要
workerTimes[i]秒。 - 山的高度降低 2,需要
workerTimes[i] + workerTimes[i] * 2秒,依此类推。
- 山的高度降低 1,需要
返回一个整数,表示工人们使山的高度降低到 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 <= 1051 <= workerTimes.length <= 1041 <= workerTimes[i] <= 106
解题思路
方法一:二分查找
我们注意到,如果所有的工人能在 秒内将山的高度降低到 ,那么对于任意 ,工人们也能在 秒内将山的高度降低到 。因此,我们可以使用二分查找的方法找到最小的 ,使得工人们能在 秒内将山的高度降低到 。
我们定义一个函数 ,表示工人们能否在 秒内将山的高度降低到 。具体地,我们遍历每一个工人,对于当前工人 ,假设他在 秒内降低了 的高度,那么我们可以得到一个不等式:
解不等式得到:
我们可以将所有工人的 相加,得到总共降低的高度 ,如果 ,那么说明工人们能在 秒内将山的高度降低到 。
接下来,我们确定二分查找的左边界 ,由于最少有一个工作,且每个工人的工作时间不超过 ,要想使山的高度降低到 ,最少需要 秒,因此我们可以确定二分查找的右边界 。然后我们不断地将区间 二分,直到 ,此时 即为答案。
时间复杂度 ,其中 为工人的数量,而 为二分查找的右边界,本题中 。空间复杂度 。
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)
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | 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 |
面试官常问的追问
外企场景- 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?
常见陷阱
外企场景- 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.
进阶变体
外企场景- 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.