Is Subsequence
Given two strings s and t, determine whether s is a subsequence of t.
Open on LeetCode ↗Intuition
The trap is reading subsequence as substring. They differ by one word: a substring must be contiguous, a subsequence may skip characters as long as the relative order survives. So for s = 'abc' and t = 'ahbgdc' the answer is true even though a, b and c are scattered — and any solution that resets progress when it hits a mismatch will report false. That reset is the actual bug. Walk both strings with a pointer each and make them behave differently on purpose: j walks through t on every single step, no exceptions, while i advances into s only when it finds the character it is waiting for. A mismatch discards one character of t and costs you nothing you had already earned. Taking the leftmost match every time is also safe, not just convenient — an earlier match leaves strictly more of t available for the rest of s, so it can never lose to a later one. The invariant is that s[0:i] is always a subsequence of the part of t already consumed, and if i reaches the end of s you have your proof, no matter how much of t is left over.
Approach
Two pointers with asymmetric movement
Put i at the start of s and j at the start of t. The whole algorithm lives in the fact that these two move under different rules: j increments unconditionally on every iteration, i only when s[i] == t[j]. Writing them as a symmetric pair is what produces the substring solution by accident, so the asymmetry deserves to be stated out loud.
Consume greedily on a match
When the characters agree, advance both — you have matched one more character of s and used up one of t. When they disagree, advance only j, discarding that character of t while every match so far stays banked. Greedy is provably correct here: matching s[i] at the earliest possible position in t leaves the largest possible suffix for the characters still to come.
Decide on i, not j
The loop ends when either string runs out. Return whether i reached the end of s — that is the only question. Leftover characters in t are irrelevant and testing j instead is a classic wrong answer: 'abc' is a subsequence of 'abcdef' even though four characters of t go unused.
Solution & live demo
Edge cases
The empty string is a subsequence of everything; i already equals len(s) so the loop never runs and the check returns true.
The loop exits at once with i still at 0, so the answer is false — nothing can be matched against nothing.
t runs out before i reaches the end of s and the result is false; a length comparison up front makes this O(1).
The follow-up scenario. Precompute, for each position in t and each letter, the next occurrence of that letter — then each query costs O(len(s)) instead of O(len(t)).