文章目录
题目
标题和出处
标题:使绳子变成彩色的最短时间
难度
5 级
题目描述
要求
Alice 把 n \texttt{n} n 个气球排列在一根绳子上。给定一个下标从 0 \texttt{0} 0 开始的字符串 colors \texttt{colors} colors,其中 colorsi \texttt{colorsi} colorsi 是第 i \texttt{i} i 个气球的颜色。
Alice 想要把绳子装扮成彩色 。她不希望两个连续的气球涂着相同的颜色,所以她请 Bob 帮忙。Bob 可以从绳子上移除一些气球使绳子变成彩色 。给定一个下标从 0 \texttt{0} 0 开始的整数数组 neededTime \texttt{neededTime} neededTime,其中 neededTimei \texttt{neededTimei} neededTimei 是 Bob 从绳子上移除第 i \texttt{i} i 个气球需要的时间(以秒为单位)。
返回 Bob 使绳子变成彩色 需要的最少时间。
示例
示例 1:

输入: colors = "abaac", neededTime = 1,2,3,4,5 \texttt{colors = "abaac", neededTime = 1,2,3,4,5} colors = "abaac", neededTime = 1,2,3,4,5
输出: 3 \texttt{3} 3
解释:在上图中, 'a' \texttt{`a'} 'a' 是蓝色, 'b' \texttt{`b'} 'b' 是红色, 'c' \texttt{`c'} 'c' 是绿色。
Bob 可以移除下标 2 \texttt{2} 2 的蓝色气球。这将花费 3 \texttt{3} 3 秒。
移除后,不存在两个连续的气球涂着相同的颜色。总时间是 3 \texttt{3} 3。
示例 2:

输入: colors = "abc", neededTime = 1,2,3 \texttt{colors = "abc", neededTime = 1,2,3} colors = "abc", neededTime = 1,2,3
输出: 0 \texttt{0} 0
解释:绳子已经是彩色的。Bob 不需要从绳子上移除任何气球。
示例 3:

输入: colors = "aabaa", neededTime = 1,2,3,4,1 \texttt{colors = "aabaa", neededTime = 1,2,3,4,1} colors = "aabaa", neededTime = 1,2,3,4,1
输出: 2 \texttt{2} 2
解释:Bob 会移除下标 0 \texttt{0} 0 和下标 4 \texttt{4} 4 处的气球。每个气球各需要 1 \texttt{1} 1 秒来移除。
移除后,不存在两个连续的气球涂着相同的颜色。总时间是 1 + 1 = 2 \texttt{1} + \texttt{1} = \texttt{2} 1+1=2。
数据范围
- n = colors.length = neededTime.length \texttt{n} = \texttt{colors.length} = \texttt{neededTime.length} n=colors.length=neededTime.length
- 1 ≤ n ≤ 10 5 \texttt{1} \le \texttt{n} \le \texttt{10}^\texttt{5} 1≤n≤105
- 1 ≤ neededTimei ≤ 10 4 \texttt{1} \le \texttt{neededTimei} \le \texttt{10}^\texttt{4} 1≤neededTimei≤104
- colors \texttt{colors} colors 仅由小写英语字母组成
解法
思路和算法
将字符串 colors \textit{colors} colors 分成连续非空子片段,每个子片段由相同字符组成,且任意两个相邻子片段的字符都不同。移除气球使绳子上的任意两个相邻气球不同色,等价于从字符串 colors \textit{colors} colors 中移除字符使剩余的任意两个相邻字符不同。
为了使字符串 colors \textit{colors} colors 中剩余的任意两个相邻字符不同,每个片段最多只能保留 1 1 1 个字符,因此对于长度为 k k k 的片段,需要移除 k − 1 k - 1 k−1 个字符,当 k = 1 k = 1 k=1 时也成立。
为了使总时间最少,对于长度为 k k k 的片段,应移除用时最少的 k − 1 k - 1 k−1 个气球,保留用时最多的 1 1 1 个气球,理由如下。
假设移除每个气球的时间分别是 t 1 t_1 t1 到 t k t_k tk,其中 t k t_k tk 为最大值,记 T T T 为移除当前片段中的用时最少的 k − 1 k - 1 k−1 个气球且保留用时 t k t_k tk 的气球的总用时。如果保留的气球不是用时 t k t_k tk 的气球,则将保留的气球的用时记为 t j t_j tj,将此时移除 k − 1 k - 1 k−1 个气球的总用时记为 T ′ T' T′,则 t j ≤ t k t_j \le t_k tj≤tk, T ′ = T + t k − t j ≥ T T' = T + t_k - t_j \ge T T′=T+tk−tj≥T,总用时不可能小于 T T T。因此总时间最少的方法是移除用时最少的 k − 1 k - 1 k−1 个气球,保留用时最多的 1 1 1 个气球。
根据上述分析,可以使用贪心的思想计算使绳子变成彩色需要的最少时间。
具体做法是,从左到右遍历字符串 colors \textit{colors} colors 和数组 neededTime \textit{neededTime} neededTime,遍历过程中维护所有气球的总用时 totalTime \textit{totalTime} totalTime、当前片段的气球的用时之和 segmentTime \textit{segmentTime} segmentTime 与当前片段的最大用时 maxTime \textit{maxTime} maxTime。当遍历到下标 i i i 时,执行如下操作。
-
移除第 i i i 个气球需要的时间是 neededTime i \textit{neededTime}i neededTimei,将 segmentTime \textit{segmentTime} segmentTime 增加 neededTime i \textit{neededTime}i neededTimei,并用 neededTime i \textit{neededTime}i neededTimei 更新 maxTime \textit{maxTime} maxTime。
-
如果 i = n − 1 i = n - 1 i=n−1 或 colors i ≠ colors i + 1 \textit{colors}i \ne \textit{colors}i + 1 colorsi=colorsi+1,则下标 i i i 是当前片段的结束下标,当前片段保留用时最多的 1 1 1 个气球且移除其余所有气球的最少时间是 segmentTime − maxTime \textit{segmentTime} - \textit{maxTime} segmentTime−maxTime,将 totalTime \textit{totalTime} totalTime 增加 segmentTime − maxTime \textit{segmentTime} - \textit{maxTime} segmentTime−maxTime,然后将 segmentTime \textit{segmentTime} segmentTime 和 maxTime \textit{maxTime} maxTime 都更新为 0 0 0。
遍历结束之后, totalTime \textit{totalTime} totalTime 即为使绳子变成彩色需要的最少时间。
代码
java
class Solution {
public int minCost(String colors, int[] neededTime) {
int totalTime = 0;
int segmentTime = 0;
int maxTime = 0;
int n = colors.length();
for (int i = 0; i < n; i++) {
segmentTime += neededTime[i];
maxTime = Math.max(maxTime, neededTime[i]);
if (i == n - 1 || colors.charAt(i) != colors.charAt(i + 1)) {
totalTime += segmentTime - maxTime;
segmentTime = 0;
maxTime = 0;
}
}
return totalTime;
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 colors \textit{colors} colors 和数组 neededTime \textit{neededTime} neededTime 的长度。需要遍历字符串和数组一次计算最短时间,每个下标处的操作时间是 O ( 1 ) O(1) O(1)。
-
空间复杂度: O ( 1 ) O(1) O(1)。