Skip to content

Latest commit

 

History

History
90 lines (75 loc) · 3.78 KB

File metadata and controls

90 lines (75 loc) · 3.78 KB

Hints

  • What should you do when you see consecutive balloons of the same color?
  • Is it always optimal to keep the balloon with the highest removal time in a group?

Breakdowns

  1. How do you ensure no two adjacent balloons have the same color?
  • For every group of consecutive balloons with the same color, you must remove all but one. The optimal one to keep is the one with the highest neededTime.
  1. How do you efficiently calculate the minimum total removal time?
  • For each group, sum all neededTime and subtract the maximum in the group. Repeat for all groups.

Key Insights

  • This is a classic "group by consecutive" problem, where you process runs of the same value.
  • The greedy choice is always to keep the balloon with the highest removal cost in each group, removing the rest.
  • You can solve this in a single pass with two pointers or a running max/sum.
  • This pattern appears in other problems like 1446. Consecutive Characters.

Two Pointers (Group by Consecutive) + Greedy

Idea!! For each group of consecutive balloons with same color, remove all but the one with the highest neededTime.

We try to group the consecutive balloons with the same color, and remove the balloons of the same color by removing all but keep the balloon with the maximum time.

a, a, a
2, 3, 1

We must remove 1, 2 and keep 3, total cost is sum of group - max of group, which is 1 + 2 + 3 - 3 = 3.

If we have repeated characters, we need to remove all of them except one - the "most expensive" character to remove.

fun minCost(colors: String, neededTime: IntArray): Int {
    val n = colors.length
    var i = 0
    var totalTime = 0
    while (i < n) {
        // Group: same color, remove all except the maximum time.
        // I made a mistake here: I just remove the minimum time, but failed 
        // the case that there are multiple balloons with different times.
        val start = i
        var groupMax = neededTime[start]
        var groupSum = neededTime[start]
        i++
        while (i < n && colors[start] == colors[i]) {
            groupMax = maxOf(groupMax, neededTime[i])
            groupSum += neededTime[i]
            i++
        }
        totalTime += (groupSum - groupMax)
    }
    return totalTime
}

// Or equivalently, this is the same approach as discussion, but not group by consecutive.
fun minCost(colors: String, neededTime: IntArray): Int {
    var totalCost = 0
    var groupSum = neededTime.first()
    var groupMax = neededTime.first()
    for (i in 1 until colors.length) {
        if (colors[i - 1] == colors[i]) { // Expand the group
            groupSum += neededTime[i]
            groupMax = maxOf(groupMax, neededTime[i])
        } else { // Reset the group
            totalCost += groupSum - groupMax
            groupSum = neededTime[i]
            groupMax = neededTime[i]
        }
    }
    // Don't forget to add the last group, like "a, a, a"
    totalCost += groupSum - groupMax
    return totalCost
}
  • Time Complexity: O(N), where N is the length of colors.
  • Space Complexity: O(1).

Edge Cases

  • Single balloon: answer is 0 (should not remove anything).
  • All balloons are unique colors: answer is 0.
  • All balloons are the same color: remove all but the one with the highest neededTime.
  • Large input with many consecutive groups: make sure to reset group tracking correctly.

Similar or Follow-up Problems