#844 Backspace String Compare
the problem
In plain words
Two strings s and t are typed into empty text boxes, where '#' means Backspace. A Backspace on an empty box does nothing. Return true if both boxes end up holding the same text.
in s = "ab#c", t = "ad#c"
out true
Both become "ac".
in s = "ab##", t = "c#d#"
out true
Both become empty.
in s = "a#c", t = "b"
out false
"c" is not "b".
- 1 ≤ s.length, t.length ≤ 200
- Only lowercase letters and '#'
- Follow-up: O(n) time and O(1) extra space
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternStack for matching & nesting
Typing with Backspace is a stack: a letter pushes, '#' pops. For O(1) space, read from the end instead: every '#' tells you to skip one of the letters before it, so you can produce the surviving letters one by one and compare as you go.
solutions
From brute force to optimal
Replay the keys: append letters, delete the last character on '#'. Compare the two results.
- For each key: letter → append; '#' → deleteCharAt(length − 1) if not empty.
- Do it for s and for t.
- Compare with equals.
Each key is handled once; deleting the last character of a StringBuilder is O(1).
The two typed strings.
class Solution { public boolean backspaceCompare(String s, String t) { return type(s).equals(type(t)); } /** Replays the keystrokes. The end of the builder is the top of a stack. */ private String type(String keys) { StringBuilder typed = new StringBuilder(); for (char c : keys.toCharArray()) { if (c != '#') typed.append(c); // push else if (typed.length() > 0) typed.deleteCharAt(typed.length() - 1); // pop ('#' on empty does nothing) } return typed.toString(); }}From the end of each string, skip characters erased by later '#'s to find the next survivor. Compare survivors pair by pair.
- i, j start at the last index of s and t.
- Move each pointer left: '#' → skip++; a letter while skip > 0 → skip−−; else stop — that letter survives.
- If one string runs out first → false. Different survivors → false. Otherwise step both left and repeat.
Each pointer only moves left, once per character.
Two indices and two skip counters.
class Solution { public boolean backspaceCompare(String s, String t) { int i = s.length() - 1, j = t.length() - 1; while (i >= 0 || j >= 0) { i = nextKept(s, i); // next character that survives, or -1 j = nextKept(t, j); if (i < 0 || j < 0) return i < 0 && j < 0; // one string ran out: equal only if both did if (s.charAt(i) != t.charAt(j)) return false; i--; j--; } return true; } /** Walks left from i, skipping characters that a later '#' erases. */ private int nextKept(String keys, int i) { int skip = 0; // how many '#' are still waiting to erase while (i >= 0) { if (keys.charAt(i) == '#') skip++; else if (skip > 0) skip--; // this character is erased else break; // a survivor i--; } return i; }}in the room
How to say it in the interview
talk track
- Give the stack version first — it's two short loops and clearly correct.
- For the O(1) follow-up, explain why the end is easier: going forward you can't know whether a letter survives, going backward you already know how many '#' are waiting.
- Test aloud with "ab##" vs "c#d#" and with a '#' on an empty box.
traps
- Deleting on '#' when the builder is empty —
deleteCharAt(-1)throws. - In the backward scan, stopping when only one string runs out and returning true.
- Using
Stringconcatenation andsubstringin a loop: every step copies the whole string.
what they ask next
Follow-ups
What if the editor also had a Delete key that removes the character after the cursor?
Then you need a real cursor: two stacks (text left of the cursor and text right of it) — the same idea as an editor's gap buffer.
before you submit
Edge cases to test
- A '#' on an empty box does nothing: "#a" types "a".
- Both may type nothing at all: "ab##" and "c#d#" → true.
- Only one side runs out: "abc" vs "abc#" → false.
practise next
Similar problems
- #71Simplify PathMediumin Stacks
- #20Valid ParenthesesEasyin Stacks
- #125Valid PalindromeEasyin Two Pointers