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

文章目录

题目

标题和出处

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

出处: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)。

相关推荐
Tisfy2 天前
LeetCode 0678.有效的括号字符串:O(n)+O(1)一次遍历
算法·leetcode·字符串·题解·贪心·括号匹配
伟大的车尔尼3 天前
贪心题目:坏了的计算器
贪心
lvwangshu5 天前
T1 称重(weight)题解
题解·贪心·总结·技巧·性质题·思维好题
伟大的车尔尼5 天前
贪心题目:十-二进制数的最少数目
贪心
伟大的车尔尼7 天前
贪心题目:不含 AAA 或 BBB 的字符串
贪心
伟大的车尔尼8 天前
贪心题目:最少的后缀翻转次数
贪心
lvwangshu9 天前
P12960 毒药 题解
动态规划·题解·贪心·技巧·性质题·思维好题
伟大的车尔尼18 天前
贪心题目:优势洗牌
贪心
Logic10118 天前
C语言/数据结构动态规划题解:Kadane算法求最大子数组和——O(n)时间O(1)空间
c语言·数据结构·动态规划·贪心·时间复杂度·算法题·最大子数组和