开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情
刷题的日常-2023年2月11号
一天一题,保持脑子清爽
装满杯子需要的最短总时长
来自leetcode的 2335 题,题意如下: 现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。
给你一个下标从 0 开始、长度为 3 的整数数组 amount ,其中 amount[0]、amount[1] 和 amount[2] 分别表示需要装满冷水、温水和热水的杯子数量。返回装满所有杯子所需的 最少 秒数。
理解题意
通过题意,我们可以将信息整理如下:
- 题目给出一个数组,数组里固定是三个数,代表三种不同温度的水杯
- 要求我们往杯子里装水,一秒最多可以装两种不同温度的水
- 返回全部杯子装满需要的时间
做题思路
这道题可以用贪心解决。如果最多杯子的水杯大于等于其他两种杯子的和,那么时间总是最大数量杯子所用时间,因为其它两种杯子总能和其找到匹配。
如果最大数量的杯子要小于其它两种杯子的和,意味着可能会有杯子不能匹配到。假设杯子的数量为x,y,z,并且有 x < y < z。那么 z 和 x,y匹配完之后将多出 x + y - z 个。我们设 t = x + y - z,这多出的部分可以在 x 和 y 两种内部自己匹配,能匹配的次数为 t / 2。
问题就在于,x 和 y 会不会小于 t / 2 呢?我们来看看
- 我们知道 t = x + y - z
- 又因为 x < y < z,所以有 y − z ≤ 0
- 那么就有 (t = x + y − z) ≤ x ≤ y
- 也就是说 x 和 y 始终能匹配对应的 t / 2 个杯子
我们将 t / 2 个杯子在 x 和 y 内部消掉之后,剩余的和 z 匹配即可。
代码实现
代码实现如下:
public class Solution {
public int fillCups(int... amount) {
Arrays.sort(amount);
if (amount[2] >= amount[0] + amount[1]) {
return amount[2];
}
return (amount[0] + amount[1] + amount[2] + 1) / 2;
}
}