You are given a string colors
where each character represents the color of a balloon in a rope, and an array neededTime
where neededTime[i]
is the time needed to remove the i
-th balloon.
The goal is to make the rope "colorful," which means no two adjacent balloons have the same color. To achieve this, you can remove balloons, and the cost of removing the i
-th balloon is neededTime[i]
. Your task is to find the minimum total time required to make the rope colorful.
Constraints:
First, let's understand the problem intuitively. If two or more adjacent balloons have the same color, we must remove some of them to ensure only one remains in that group. The naive approach is to try all combinations of removals, but that's inefficient.
Instead, for each group of consecutive balloons with the same color, we only need to keep one balloon (the one with the highest neededTime
cost, since removing cheaper ones costs less). So, for each group, we remove all but the most "expensive" balloon to minimize the total removal time.
This leads us from a brute-force approach to a greedy one: always keep the balloon with the highest neededTime
in each group of consecutive same-colored balloons.
The solution uses a greedy algorithm, processing the rope from left to right:
totalTime
).colors
string, tracking groups of consecutive balloons with the same color.neededTime
values and find the maximum in that group.totalTime
and move to the next group.
Input:
colors = "aabaa"
neededTime = [1,2,3,4,1]
Steps:
neededTime
are 1 and 2. Remove the one with smaller cost (remove index 0, cost 1).neededTime
are 4 and 1. Remove the one with smaller cost (remove index 4, cost 1).
Brute-force approach: Try all combinations of removals for adjacent duplicates. This is exponential in time, O(2^n), and impractical for large inputs.
Optimized (greedy) approach:
colors
. We only need a single pass through the string.The problem asks us to minimize the time to make a rope colorful by removing adjacent same-colored balloons. The key insight is that for each group of consecutive same-colored balloons, we should keep the one with the highest removal cost and remove the rest. This greedy approach leads to an efficient O(n) solution that is both simple and elegant.
class Solution:
def minCost(self, colors: str, neededTime: list[int]) -> int:
totalTime = 0
n = len(colors)
i = 0
while i < n:
sumTime = neededTime[i]
maxTime = neededTime[i]
j = i + 1
while j < n and colors[j] == colors[i]:
sumTime += neededTime[j]
maxTime = max(maxTime, neededTime[j])
j += 1
totalTime += sumTime - maxTime
i = j
return totalTime
class Solution {
public:
int minCost(string colors, vector<int>& neededTime) {
int totalTime = 0, n = colors.size(), i = 0;
while (i < n) {
int sumTime = neededTime[i], maxTime = neededTime[i];
int j = i + 1;
while (j < n && colors[j] == colors[i]) {
sumTime += neededTime[j];
maxTime = max(maxTime, neededTime[j]);
j++;
}
totalTime += sumTime - maxTime;
i = j;
}
return totalTime;
}
};
class Solution {
public int minCost(String colors, int[] neededTime) {
int totalTime = 0, n = colors.length(), i = 0;
while (i < n) {
int sumTime = neededTime[i];
int maxTime = neededTime[i];
int j = i + 1;
while (j < n && colors.charAt(j) == colors.charAt(i)) {
sumTime += neededTime[j];
maxTime = Math.max(maxTime, neededTime[j]);
j++;
}
totalTime += sumTime - maxTime;
i = j;
}
return totalTime;
}
}
var minCost = function(colors, neededTime) {
let totalTime = 0, n = colors.length, i = 0;
while (i < n) {
let sumTime = neededTime[i];
let maxTime = neededTime[i];
let j = i + 1;
while (j < n && colors[j] === colors[i]) {
sumTime += neededTime[j];
maxTime = Math.max(maxTime, neededTime[j]);
j++;
}
totalTime += sumTime - maxTime;
i = j;
}
return totalTime;
};