Idea
Use a stack to keep track of characters.
Code
“Real” Stack
1 | class Solution { |
Two Pointers
1 | class Solution { |
(explained by ChatGPT)
Instead of a stack data structure, it reuses the string s
itself as the stack.
Variables:
j
= the read index (iterate through the original string, left to right).i
= the write index (the “top of stack” insides
).
The loop
1 | for (int j = 0; j < n; ++j, ++i) { |
s[i] = s[j]
→ copies the current char onto the “stack”.- Then it checks: if the top two (
s[i]
ands[i-1]
) are equal → we undo both by settingi -= 2
.
So i
always points to where the next character should be written.
At the end, s.substr(0, i)
returns the “stack contents”.
Why it works
Every char is processed exactly once (
j
goes 0..n-1).Each char is either:
- kept (written at position
i
), or - canceled out with its duplicate (via
i -= 2
).
- kept (written at position
The logic of
i -= 2
ensures that when duplicates are removed, the stack shrinks by 2, just like popping from a real stack.
Thus this algorithm simulates the push-pop behavior of a stack, but in place, with O(1)
extra memory.
Quick dry run
s = "abbaca"
j=0
:s[0]='a'
, push → stack ="a"
(i=1
)j=1
:s[1]='b'
, push →"ab"
(i=2
)j=2
:s[2]='b'
, push →"abb"
→ dup! → pop →"a"
(i=1
)j=3
:s[3]='a'
, push →"aa"
→ dup! → pop →""
(i=0
)j=4
:s[4]='c'
, push →"c"
(i=1
)j=5
:s[5]='a'
, push →"ca"
(i=2
)
Result = s.substr(0,2) = "ca"
✅
Summary
This works because:
i
serves as a simulated stack pointer.s[i] = s[j]
is like “pushing” the char.i -= 2
is like “popping” two chars when a duplicate is found.- The final prefix of
s
up toi
is the answer.
So it’s a stack algorithm implemented in-place.
Failed Attempt (use recursion)
recursion is having MLE issue
1 | class Solution { |