刷题的日常-装满杯子需要的最短总时长

159 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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;
    }
}