AlgoMaster Logo

Removing Stars From a String

Last Updated: April 1, 2026

medium
4 min read

Understanding the Problem

Think of typing in a text editor where * acts like a backspace key. Every time you encounter a *, it deletes the most recent non-star character you typed. The string is processed left to right, and each star removes exactly one character to its left.

The key insight is that a star always removes the closest non-star character to its left. So if you have "ab*", the * removes 'b' and you are left with "a". If you have "ab**", the first * removes 'b' and the second * removes 'a', leaving an empty string.

This "type a character, then potentially delete it" pattern is exactly what a stack handles well. Characters go on the stack, and stars pop them off.

Key Constraints:

  • 1 <= s.length <= 10^5 → With up to 100,000 characters, we need an O(n) or O(n log n) approach. An O(n^2) approach (repeatedly scanning and removing) could hit 10^10 operations in the worst case, which is too slow.
  • s consists of lowercase English letters and stars * → Simple character set, no special handling needed beyond distinguishing stars from letters.
  • The operation can always be applied → Every star is guaranteed to have a non-star character to its left. We do not need to handle the case where a star has nothing to remove.

Approach 1: Brute Force Simulation

Intuition

The most straightforward way to handle this: find a star, remove it along with the character to its left, and repeat. Each time you remove a star, you scan the string again to find the next one. This directly simulates the operation described in the problem.

It is simple to understand but inefficient. Every removal operation requires rebuilding or shifting part of the string, and you have to scan from the beginning each time because earlier removals might shift positions.

Algorithm

  1. Convert the string to a mutable list of characters.
  2. Scan the list from left to right looking for a *.
  3. When you find a * at index i:
    • Remove the * at index i.
    • Remove the character at index i - 1 (the closest non-star to its left).
    • Restart the scan from the adjusted position.
  4. When a full scan finds no stars, convert the list back to a string and return it.

Example Walkthrough

1Scan left to right, looking for first '*'
0
l
i
1
e
2
e
3
t
4
*
5
*
6
c
7
o
8
d
9
*
10
e
1/7

Code

Every time we encounter a star, we remove two characters from the list, which shifts all subsequent elements. What if instead of modifying the string with costly removals, we built the result incrementally, processing each character just once?

Approach 2: Stack (StringBuilder)

Intuition

Instead of repeatedly modifying the string, we can build the result in a single pass. Think of it like typing on a keyboard. As you scan left to right: if the character is a letter, type it (push onto a stack). If the character is a *, press backspace (pop the most recent letter from the stack).

After processing every character, whatever remains in the stack is the final string. Since we only need to add to the end and remove from the end, a StringBuilder (or list) works perfectly as our "stack." No shifting, no rescanning.

Algorithm

  1. Initialize an empty StringBuilder (acting as a stack).
  2. Iterate through each character in s:
    • If the character is *, remove the last character from the StringBuilder (pop).
    • Otherwise, append the character to the StringBuilder (push).
  3. Return the StringBuilder as a string.

Example Walkthrough

1Start: scan string left to right, stack is empty
0
l
i
1
e
2
e
3
t
4
*
5
*
6
c
7
o
8
d
9
*
10
e
1/6

Code

The stack approach is already O(n) time, but we are using O(n) extra space for a separate data structure. What if we could use the input array itself as the stack, writing results in-place with a pointer?

Approach 3: In-Place with Write Pointer

Intuition

Instead of maintaining a separate stack, we can use a write pointer on a character array. As we scan left to right, we overwrite the array in place. A pointer write tracks where the next surviving character should go.

When we see a letter, write it at position write and advance the pointer. When we see a *, move the pointer back by one, effectively "deleting" the last written character. At the end, everything from index 0 to write - 1 is the result.

Algorithm

  1. Convert the string to a character array.
  2. Initialize a write pointer write = 0.
  3. Iterate through each character:
    • If the character is *, decrement write by 1.
    • Otherwise, write the character at arr[write] and increment write.
  4. Return the substring from index 0 to write.

Example Walkthrough

1Initialize: write=0, start scanning left to right
0
write
l
read
1
e
2
e
3
t
4
*
5
*
6
c
7
o
8
d
9
*
10
e
1/6

Code