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

a person standing at the entrance to a cave

题目

现有一台饮水机,可以制备冷水、温水和热水。每秒钟,可以装满 2不同 类型的水或者 1 杯任意类型的水。

给你一个下标从 0 开始、长度为 3 的整数数组 amount ,其中 amount[0]amount[1]amount[2] 分别表示需要装满冷水、温水和热水的杯子数量。返回装满所有杯子所需的 最少 秒数。

示例 1:

1
2
3
4
5
6
7
8
输入:amount = [1,4,2]
输出:4
解释:下面给出一种方案:
第 1 秒:装满一杯冷水和一杯温水。
第 2 秒:装满一杯温水和一杯热水。
第 3 秒:装满一杯温水和一杯热水。
第 4 秒:装满一杯温水。
可以证明最少需要 4 秒才能装满所有杯子。

示例 2:

1
2
3
4
5
6
7
8
9
10
输入:amount = [5,4,4]
输出:7
解释:下面给出一种方案:
第 1 秒:装满一杯冷水和一杯热水。
第 2 秒:装满一杯冷水和一杯温水。
第 3 秒:装满一杯冷水和一杯温水。
第 4 秒:装满一杯温水和一杯热水。
第 5 秒:装满一杯冷水和一杯热水。
第 6 秒:装满一杯冷水和一杯温水。
第 7 秒:装满一杯热水。

示例 3:

1
2
3
输入:amount = [5,0,0]
输出:5
解释:每秒装满一杯冷水。

题解

排序+递归;

考虑到水种类只有3,且每种水数据范围只有100,可以使用递归;

为了尽可能的凑成多的对数,我们可以每次取剩余数量最多且不为 0 的两类水进行成组(因此每次处理前需要先对当前 amount 进行排序),直到没有水剩余,或只有一类水的剩余数据量不为 0(剩下的水只能独自生成)。

1
2
3
4
5
6
7
8
9
public int fillCups(int[] amount) {
Arrays.sort(amount);
if (amount[1] == 0){
return amount[2];
}
amount[1] --;
amount[2] --;
return 1 + fillCups(amount);
}