AlgoMaster Logo

Removing Stars From a String

mediumFrequency6 min readUpdated June 23, 2026

Understanding the Problem

A * behaves like a backspace key in a text editor. It deletes the most recent non-star character to its left, and the string is processed left to right.

Since each star removes the closest surviving character to its left, the order of removals is fully determined. In "ab*", the * removes 'b' and leaves "a". In "ab**", the first * removes 'b' and the second removes 'a', leaving an empty string. A star can also cancel a character that an earlier star already exposed, so removals can chain backward through the string.

This "add a character, then undo the most recent addition" behavior maps directly onto a stack: letters get pushed, and stars pop the top.

Key Constraints:

  • 1 <= s.length <= 10^5 → With up to 100,000 characters, an O(n^2) approach that repeatedly shifts the string can reach about 10^10 operations, too slow under typical limits. A single-pass O(n) solution is the target.
  • s consists of lowercase English letters and stars * → The only distinction that matters is letter versus star.
  • The operation can always be applied → Every star has a non-star character to its left, so we never have to handle a star with nothing to remove.

Approach 1: Brute Force Simulation

Intuition

Simulate the operation literally: find a star, remove it along with the character to its left, then continue scanning. This mirrors the problem statement step for step.

The cost shows up in the removals. Deleting a character from the middle of a string or list shifts every element after it, and a fresh scan has to resume near the deletion point because positions changed. With many stars, that shifting work dominates.

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

The repeated shifting is the bottleneck. The next approach builds the result in a single pass instead, touching each character exactly once.

Approach 2: Stack (StringBuilder)

Intuition

Build the result in a single pass using a stack. As we scan left to right, a letter gets pushed onto the stack, and a star pops the top element. The pop discards the most recent surviving letter, which is the closest non-star to the left of that star.

After the scan, the stack holds the answer in order. Because every operation only adds to or removes from the end, a StringBuilder (or list) serves as the stack, with no shifting or 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 runs in O(n) time but allocates a separate structure for O(n) extra space. The next approach removes that allocation by treating the input array itself as the stack, using a single write pointer.

Approach 3: In-Place with Write Pointer

Intuition

Reuse the character array as the stack. A write pointer marks where the next surviving character belongs, and the loop variable acts as the read pointer scanning left to right.

For a letter, store it at index write and advance write. For a *, decrement write, which logically removes the last stored character so the next letter overwrites it. At the end, indices 0 through write - 1 hold 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