2335-装满杯子需要的最短总时长

Raphael Liu Lv10

现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 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

方法一:贪心 + 分类讨论

假设不同类型杯子的数量分别为 x, y 和 z,其中 x \le y \le z。

  • 如果 x + y \le z,那么每次装满 z 的时候,可以同时装满 x 或 y,因此总时长为 z。

  • 如果 x + y \gt z,令 t = x + y - z,因为 y - z \le 0,所以 t = x + y - z \le x \le y。

    • 如果 t 为偶数,相应的 x + y + z 也为偶数,那么可以同时将 x 和 y 都装满 \dfrac{t}{2,剩余的 x + y - t = z,可以同时装满,因此总时长为 \dfrac{t}{2} + z = \dfrac{x + y - z}{2} + z = \dfrac{x + y + z}{2。

    • 如果 t 为奇数,相应的 x + y + z 也为奇数,那么可以同时将 x 和 y 都装满 \dfrac{t - 1/2,剩余的 x + y - (t - 1) = z + 1 \gt z,因此总时长为 \dfrac{t - 1/2} + z + 1 = \dfrac{x + y - z - 1/2} + z + 1 = \dfrac{x + y + z + 1/2。

    因此无论 t 为奇数还是偶数,总时长都为 \big \lceil \dfrac{x + y + z}{2} \big \rceil。

[sol1-Python3]
1
2
3
4
5
6
class Solution:
def fillCups(self, amount: List[int]) -> int:
amount.sort()
if amount[2] > amount[1] + amount[0]:
return amount[2]
return (sum(amount) + 1) // 2
[sol1-C++]
1
2
3
4
5
6
7
8
9
10
class Solution {
public:
int fillCups(vector<int>& amount) {
sort(amount.begin(), amount.end());
if (amount[2] > amount[1] + amount[0]) {
return amount[2];
}
return (accumulate(amount.begin(), amount.end(), 0) + 1) / 2;
}
};
[sol1-Java]
1
2
3
4
5
6
7
8
9
class Solution {
public int fillCups(int[] amount) {
Arrays.sort(amount);
if (amount[2] > amount[1] + amount[0]) {
return amount[2];
}
return (amount[0] + amount[1] + amount[2] + 1) / 2;
}
}
[sol1-C#]
1
2
3
4
5
6
7
8
9
public class Solution {
public int FillCups(int[] amount) {
Array.Sort(amount);
if (amount[2] > amount[1] + amount[0]) {
return amount[2];
}
return (amount[0] + amount[1] + amount[2] + 1) / 2;
}
}
[sol1-C]
1
2
3
4
5
6
7
8
9
10
11
static int cmp(const void *pa, const void *pb) {
return *(int *)pa - *(int *)pb;
}

int fillCups(int* amount, int amountSize) {
qsort(amount, amountSize, sizeof(int), cmp);
if (amount[2] > amount[1] + amount[0]) {
return amount[2];
}
return (amount[0] + amount[1] + amount[2] + 1) / 2;
}
[sol1-JavaScript]
1
2
3
4
5
6
7
var fillCups = function(amount) {
amount.sort((a, b) => a - b);
if (amount[2] > amount[1] + amount[0]) {
return amount[2];
}
return Math.floor((amount[0] + amount[1] + amount[2] + 1) / 2);
};
[sol1-Golang]
1
2
3
4
5
6
7
func fillCups(amount []int) int {
sort.Ints(amount)
if amount[2] > amount[1]+amount[0] {
return amount[2]
}
return (amount[0] + amount[1] + amount[2] + 1) / 2
}

复杂度分析

  • 时间复杂度:O(1)。

  • 空间复杂度:O(1)。

 Comments
On this page
2335-装满杯子需要的最短总时长