Remove Elements by Type and Color
Run Compression + Stack
Go step by step: try it yourself before the video and the visual. Progress saves on this device.
0 / 130 pointsSolved (Medium) 0/40Reviews 0/50Mastered 0/25Practice steps 0/15
Step 1
Know these before you start
Practise each one here, or tick what you already know
Watch the concept video if the pattern is new to you.
Step 2
Try it on paper
5โ10 minutes, no code yet
ProblemProblem statementYou are given three integer arrays types, colors, and groupSize, where types and colors have length n, and groupSize has length m.ReadHide
Problem Statement
You are given three integer arrays types, colors, and groupSize, where types and colors have length n, and groupSize has length m.
types[i]is the type of the element at indexi.colors[i]is the color of the element at indexi.groupSize[t]is the required number of elements in a removable group of typet.
In one operation, you may remove exactly groupSize[t] consecutive elements if all of them have type t and the same color. After each removal, the remaining elements become adjacent again while maintaining their relative order.
Return true if it is possible to remove all elements using a sequence of valid operations. Otherwise, return false.
Added 2026-11-08 from Srujan's LeetCode Recent AC list (photo) โ not previously in the repo.
Input / Output
Input: types = [0,1,1,0], colors = [5,3,3,5], groupSize = [2,2]
Output: true
Explanation: Remove indices 1-2 (type 1, color 3), the two 0s become
adjacent, then remove them too.
Input: types = [0,1,0], colors = [9,9,9], groupSize = [3,2]
Output: false
Explanation: No consecutive group satisfies its required size.
Input: types = [2,0,1,2], colors = [7,5,4,7], groupSize = [3,1,2]
Output: false
Explanation: Removing index 2 (type 1, groupSize 1) leaves [2,0,2],
and nothing else can be removed.
Code it on LeetCode
There's no editor for this one here yet, so solve it on LeetCode, with its own tests. Then tick My code passed below, and it joins your reviews. With your LeetCode account linked, that happens on its own.
An error or a Wrong Answer there? What each one means.
Step 6
Get it accepted
All test cases pass
Step 7
Review it so it sticks
Re-solve from memory after
The step that matters most: without reviews most of a solved problem fades within weeks. Three short re-solves, each just as you start to forget, are what make it yours.
Your notes
Three lines in your own words. They come back with this problem's reviews, so you can check yourself after recalling the solution.
Solve it yourself before you look
Reading the solution first feels like progress, but it makes the next similar problem โ and the interview version โ much harder, because you skipped the part where you figure it out. Give it an honest 20โ30 minutes. Stuck? Re-read the pattern, watch the concept video, or try the brute force first.
Hidden: approach ยท solution code
Approach
Pattern Recognition
Run compression + stack โ the same family as Remove All Adjacent Duplicates in String II. Squeeze consecutive elements with the same (type, color) into runs. A run that reaches its group's size vanishes, and its two neighbors become adjacent โ they may now be the same run and merge. A stack holds the runs seen so far, so a removal only ever affects the top.
Approach
Brute Force โ Rescan and Remove, Restarting Each Time, O(n^2)
while True:
scan left to right for the first run of length >= groupSize[t]
if none: return the array is empty
delete exactly groupSize[t] elements from that run
restart the scan from the beginning
Every deletion is an O(n) splice and there can be O(n) deletions, so this is quadratic โ but it is a direct simulation of the rules.
Optimized โ One Pass With a Stack of Runs, O(n)
stack = [] # each entry: [type, color, count]
for t, c in zip(types, colors):
if stack top has (t, c): stack top count += 1
else: push [t, c, 1]
if stack top count == groupSize[t]: pop the run
return stack is empty
Removing a run can only glue its neighbors together, and the stack's top is the left neighbor โ so the next element processed merges with it automatically. Each element is pushed and popped at most once.
Complexity
| Approach | Time | Space | Notes |
|---|---|---|---|
| Rescan and remove | O(n^2) | O(n) | O(n) splice per deletion |
| Stack of runs | O(n) | O(n) | Each element pushed/popped at most once |
Solution code
class SolutionBruteForce:
"""O(n^2) time | O(n) space โ rescan from the start after every removal."""
def canRemoveAll(self, types, colors, groupSize):
types = list(types)
colors = list(colors)
while True:
removed = False
i = 0
while i < len(types):
j = i
while (j < len(types) and types[j] == types[i]
and colors[j] == colors[i]):
j += 1
if j - i >= groupSize[types[i]]:
k = groupSize[types[i]]
del types[i:i + k]
del colors[i:i + k]
removed = True
break
i = j
if not removed:
return len(types) == 0
class Solution:
"""O(n) time | O(n) space โ one pass with a stack of runs."""
def canRemoveAll(self, types, colors, groupSize):
stack = [] # each entry: [type, color, count]
for t, c in zip(types, colors):
if stack and stack[-1][0] == t and stack[-1][1] == c:
stack[-1][2] += 1
else:
stack.append([t, c, 1])
if stack[-1][2] == groupSize[t]:
stack.pop()
return not stackOther ways to solve it
- Community solutions on LeetCode โ for many more versions, in many languages. Read them after you've solved it.
Revising this one?
- โSolve it from memory before peeking
- โSay the pattern out loud, not just the code
- โExplain it like you would to a friend
- โTry it again in a different language