题目:
给你一个下标从 0 开始的字符串数组 garbage
,其中 garbage[i]
表示第 i
个房子的垃圾集合。garbage[i]
只包含字符 'M'
,'P'
和 'G'
,但可能包含多个相同字符,每个字符分别表示一单位的金属、纸和玻璃。垃圾车收拾 一 单位的任何一种垃圾都需要花费 1
分钟。
同时给你一个下标从 0 开始的整数数组 travel
,其中 travel[i]
是垃圾车从房子 i
行驶到房子 i + 1
需要的分钟数。
城市里总共有三辆垃圾车,分别收拾三种垃圾。每辆垃圾车都从房子 0
出发,按顺序 到达每一栋房子。但它们 不是必须 到达所有的房子。
任何时刻只有 一辆 垃圾车处在使用状态。当一辆垃圾车在行驶或者收拾垃圾的时候,另外两辆车 不能 做任何事情。
请你返回收拾完所有垃圾需要花费的 最少 总分钟数。
示例 1:
输入:garbage = ["G","P","GP","GG"], travel = [2,4,3] 输出:21 解释: 收拾纸的垃圾车: 1. 从房子 0 行驶到房子 1 2. 收拾房子 1 的纸垃圾 3. 从房子 1 行驶到房子 2 4. 收拾房子 2 的纸垃圾 收拾纸的垃圾车总共花费 8 分钟收拾完所有的纸垃圾。 收拾玻璃的垃圾车: 1. 收拾房子 0 的玻璃垃圾 2. 从房子 0 行驶到房子 1 3. 从房子 1 行驶到房子 2 4. 收拾房子 2 的玻璃垃圾 5. 从房子 2 行驶到房子 3 6. 收拾房子 3 的玻璃垃圾 收拾玻璃的垃圾车总共花费 13 分钟收拾完所有的玻璃垃圾。 由于没有金属垃圾,收拾金属的垃圾车不需要花费任何时间。 所以总共花费 8 + 13 = 21 分钟收拾完所有垃圾。
示例 2:
输入:garbage = ["MMM","PGM","GP"], travel = [3,10] 输出:37 解释: 收拾金属的垃圾车花费 7 分钟收拾完所有的金属垃圾。 收拾纸的垃圾车花费 15 分钟收拾完所有的纸垃圾。 收拾玻璃的垃圾车花费 15 分钟收拾完所有的玻璃垃圾。 总共花费 7 + 15 + 15 = 37 分钟收拾完所有的垃圾。
提示:
2 <= garbage.length <= 105
garbage[i]
只包含字母'M'
,'P'
和'G'
。1 <= garbage[i].length <= 10
travel.length == garbage.length - 1
1 <= travel[i] <= 100
题目解析:
这道题目是一道模拟题,要求计算收拾并运输垃圾的最少总分钟数。这里涉及到几个关键的约束:每个房子可能有不止一种垃圾,一辆垃圾车处理一种垃圾,且在垃圾车移动或工作时,其它垃圾车不能进行操作。这意味着我们需要为每种垃圾计算单独的清理和运输时间。
解题的关键在于,我们必须计算出每辆垃圾车的最终目的地,即它必须到达的最远房子(即最后一个含有对应垃圾的房子),以及从起点到这个最远房子之间的总行驶时间。垃圾清理时间是确定的,每个房子的垃圾数量直接决定了这部分时间。而垃圾车的行驶时间则是更复杂的部分,需要对各种垃圾分别累加,直到其最后一个房子。
此外,题目中的每个房子的垃圾可能包含一个垃圾类型的多个单位,这意味着垃圾清理时间是该房子垃圾字符串的长度。考虑到这点,我们可以通过遍历garbage数组来统计每种垃圾的清理时间,以及每辆垃圾车需要移动的最终位置。
然后,我们需要遍历travel数组,并根据之前计算得出的每种垃圾最后一个需要清理的房子,累加垃圾车的行驶时间,来计算垃圾车行驶的总时间。最后,将每种垃圾的清理时间和行驶时间相加,就得到了收拾所有垃圾所需的最少总分钟数。
这道题的挑战在于需要准确地处理多个数组,并正确地累加每种垃圾的清理和运输时间。它检验了解题者对数组操作、字符串处理和基本的算法思维的掌握。
代码答案:
public int garbageCollection(String[] garbage, int[] travel) {
// 总消耗时间
int totalTime = 0;
// 每种垃圾车行驶到的最远房子的索引
int lastM = -1, lastP = -1, lastG = -1;
// 计算每种垃圾的总数量,并记录每种垃圾车行驶到的最远房子的索引
for (int i = 0; i < garbage.length; i++) {
String g = garbage[i];
// 累加每个房子的垃圾数量到总时间
totalTime += g.length();
if (g.indexOf('M') != -1) lastM = i;
if (g.indexOf('P') != -1) lastP = i;
if (g.indexOf('G') != -1) lastG = i;
}
// 为每种垃圾车行驶到最远房子累加所需时间
for (int i = 0; i < travel.length; i++) {
if (i < lastM) totalTime += travel[i];
if (i < lastP) totalTime += travel[i];
if (i < lastG) totalTime += travel[i];
}
return totalTime;
}
知识点回顾总结概览:
-
数组遍历:通过对
garbage
和travel
数组进行遍历,我们可以计算出每个房子垃圾的总数量和各种垃圾车需要行驶的总时间。 -
字符串处理:使用
String.indexOf()
方法来检查字符串g
中是否存在某个特定字符(在此案例中为 'M','P' 和 'G'),它返回指定字符在字符串中第一次出现处的索引,如果未出现则返回-1。这个方法在此被用来判断垃圾车是否需要停靠在某个房子来收拾特定种类的垃圾。 -
条件判断:利用
if
语句来决定是否累加行驶时间。如果当前房子索引i
小于lastM
、lastP
或lastG
,那么表示垃圾车需要行驶到这个房子,因此行驶时间需要累加到totalTime
中。 -
变量跟踪:通过
lastM
、lastP
和lastG
三个变量分别跟踪最后一个含有金属、纸张和玻璃垃圾的房子的索引。这些变量帮助我们决定每种类型的垃圾车需要到达的最远点,并且避免不必要的行驶。 -
流程控制:通过两个独立的循环,分别处理计算垃圾清理时间和计算垃圾车行驶时间,代码的结构保持清晰,符合单一职责原则。
-
算法设计:此解法基于一种贪心策略,即优先分别为每种垃圾处理逻辑,先确定停止点再累加时间。这种策略避免了多余的工作,如计算垃圾车不需要到达的房子的行驶时间。
知识点 | 说明 |
---|---|
数组遍历 | 计算每个房子垃圾总数量和垃圾车行驶总时间。通过遍历garbage 和travel 数组,得出结果。 |
字符串处理 | 使用String.indexOf() 确定字符在字符串中的索引来判断垃圾种类。当寻找的字符不存在时,此方法返回-1。 |
条件判断 | 利用if 语句根据最后一个含特定垃圾种类房子的索引(lastM , lastP , lastG )决定是否累加行驶时间,以决定垃圾车是否需要行驶至当前房子。 |
变量跟踪 | 通过lastM 、lastP 和lastG 变量跟踪含有金属、纸张和玻璃垃圾的最后一个房子的索引,协助决定每种垃圾车的最远行驶点,避免不必要行驶。 |
流程控制 | 使用两个独立循环分别处理垃圾清理和行驶时间计算,确保代码逻辑清晰,遵循单一职责原则。 |
算法设计 | 基于贪心策略,分别确定各种垃圾处理的停止点,然后累加时间。这种方法减少了不必要的行驶时间计算,提高了效率。 |