2335.装满杯子需要的最短总时长
【LetMeFly】2335.装满杯子需要的最短总时长
力扣题目链接:https://leetcode.cn/problems/minimum-amount-of-time-to-fill-cups/
现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 2
杯 不同 类型的水或者 1
杯任意类型的水。
给你一个下标从 0 开始、长度为 3
的整数数组 amount
,其中 amount[0]
、amount[1]
和 amount[2]
分别表示需要装满冷水、温水和热水的杯子数量。返回装满所有杯子所需的 最少 秒数。
示例 1:
输入:amount = [1,4,2] 输出:4 解释:下面给出一种方案: 第 1 秒:装满一杯冷水和一杯温水。 第 2 秒:装满一杯温水和一杯热水。 第 3 秒:装满一杯温水和一杯热水。 第 4 秒:装满一杯温水。 可以证明最少需要 4 秒才能装满所有杯子。
示例 2:
输入:amount = [5,4,4] 输出:7 解释:下面给出一种方案: 第 1 秒:装满一杯冷水和一杯热水。 第 2 秒:装满一杯冷水和一杯温水。 第 3 秒:装满一杯冷水和一杯温水。 第 4 秒:装满一杯温水和一杯热水。 第 5 秒:装满一杯冷水和一杯热水。 第 6 秒:装满一杯冷水和一杯温水。 第 7 秒:装满一杯热水。
示例 3:
输入:amount = [5,0,0] 输出:5 解释:每秒装满一杯冷水。
提示:
amount.length == 3
0 <= amount[i] <= 100
写在前面:
这道题与LeetCode 1753. 移除石子的最大得分非常类似,也可以参考1753的题解:https://blog.letmefly.xyz/2022/12/21/LeetCode 1753.移除石子的最大得分/
方法一:贪心 + 模拟
每次在三个数里面取最大的两个,接满这两个中不为0的那个,直到这三个数全部为0。
方法二:贪心 + 数学
有没有在方法一的基础上,更快地计算出结果的方法呢?
不失一般性,我们对这三个数排个序,令$amount[0]\leq amount[1]\leq amount[2]$,并将排序后的这三个数分别记为$a$、$b$、$c$。
1. 假设c足够大
那么我们优先以这样的顺序接水:
- 同时接满一杯$a$和$c$直到$a$接够
- 同时接满一杯$b$和$c$直到$b$接够
因为$c$是足够大的,所以在接够$a$和接够$b$后,$c$还需要再接$c-a-b$杯。
因此总次数就等于$a+b+(c-a-b)=c$
相当于是每次都往$c$里面倒水,在$a$或$b$没接完的时候附带着给$a$和$b$也接了。
此时有$a+b<c$
2. 假设c没有那么大
也就是说$a+b\geq c$的时候,我们每次仍然从数量最大的两个数中选择,那么最终的结果要么是$0, 0, 0$,要么是$0, 0, 1$(或$0,0,1$的其他顺序)。这里的“最终”是指,在“只同时接一杯水”之前的空杯状态。
这是因为:
- 首先,$c$需要量最多,并且$c$不足以消耗完$ab$后仍有剩余($a+b\geq c$),那么就不可能出现$0, 0, 2$的情况
- 其次,假设能出现$0, 1, 1$的情况,那么我们就能从两个$1$中各取一杯接满,这样就变成了$0, 0, 0$
综上,假如$a+b\geq c$,那么最终至多剩下1个空杯子,也就是说几乎全部是“同时接两杯水”,至多一次接水操作是“只接了一杯水”,因此总接水次数是$\lceil \frac{a+b+c}{2} \rceil$
1和2总结
首先对三种杯子排序使得$a<b<c$
若$a+b<c$,则需要接水$c$次
否则需要接水$\lceil\frac{a+b+c}{2}\rceil$
时间复杂度$O(1)$,三个数的排序时空消耗可以忽略不计
空间复杂度$O(1)$
AC代码
备注: $\lceil\frac{a+b+c}{2}\rceil=\lfloor\frac{a+b+c+1}{2}\rfloor$
C++
1 |
|
Python
1 |
|
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/128980819