The trap: the obvious solve rebuilds both strings with a stack and compares them — correct,
but O(n) space, and the follow-up explicitly asks for O(1). The two-pointer solve walks both
strings from the right, because a # only ever deletes something to its
left, so scanning backwards you always know how many deletions are pending before you
reach the character they will eat. Each side carries its own counter —
skipS and skipT — and the advance rule is:
a side keeps moving on its own while it is standing on a # or still owes a deletion,
and both sides only step together once each has settled on a surviving character.
Neither string is ever built.
O(1) extra space · every index is visited exactly once by its own pointer. Backwards is not a trick for its own sake: a # deletes leftward, so only a right-to-left scan lets you know the deletion count before you meet its victim.