贪心题目:使绳子变成彩色的最短时间

文章目录

题目

标题和出处

标题:使绳子变成彩色的最短时间

出处:1578. 使绳子变成彩色的最短时间

难度

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 时,执行如下操作。

  1. 移除第 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。

  2. 如果 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)。

相关推荐
伟大的车尔尼16 小时前
贪心题目:需要教语言的最少人数
贪心
lvwangshu1 天前
T3 涂鸦带师 题解
题解·贪心·倍增·技巧·思维好题·断环成链
吞下星星的少年·-·4 天前
牛客周赛 119B题(贪心)
算法·贪心
吞下星星的少年·-·5 天前
Div.2 CF edu195A题(数学,贪心)
数学·算法·贪心
伟大的车尔尼5 天前
贪心题目:交换一次的先前排列
贪心
lvwangshu6 天前
CF1882D Tree XOR 题解
动态规划·题解·贪心·dp·树形dp·换根dp·性质题·思维好题·推导题
伟大的车尔尼7 天前
贪心题目:救生艇
贪心
Jasmine_llq8 天前
《P8816 [CSP-J 2022] 上升点列》
数据结构·算法·贪心·排序·二维动态规划 dp·类背包状态转移
lvwangshu9 天前
字符串 题解
字符串·trie·题解·贪心·技巧·性质题·思维好题
Tisfy13 天前
LeetCode 2333.最小差值平方和:排序 + 数学计算(不用二分)
数学·算法·leetcode·题解·贪心·排序