Is Subsequence
Given two strings s and t, return true if s is a subsequence of t, or false otherwise. A subsequence is formed by deleting some (or no) characters from t without disturbing the relative positions of the remaining characters. Use two pointers moving in the same direction through s and t: advance the s-pointer only on a match, and always advance the t-pointer.
Constraints
- 0 ≤ s.length ≤ 100
- 0 ≤ t.length ≤ 104
- s and t consist only of lowercase English letters
Example
Input
s = "abc", t = "ahbgdc"Output
trueExplanation Every character of s appears in t in order: a, then b, then c.
In plain terms
- Subsequence
- A set of characters taken from a string in the same order they originally appear, even if other characters sit between them — for example, 'ace' is a subsequence of 'abcde'.
Advance the t-pointer, advance the s-pointer only on a match
0a
1h
2b
3g
4d
5c
Statusinit
i=0 (looking for 'a') and j=0 ('a') — match. i advances to 1.
What happens in this step
i = 0 (need 'a'), j = 0 (value 'a') t[j] == s[i] Match — i advances to 1, now looking for s[1]='b'.
Step 1 of 4
Steps to visualize
- Place a pointer i at the start of s and a pointer j at the start of t.
- Advance j through t one character at a time.
- Whenever tj matches si, advance i as well.
- Continue until i reaches the end of s (a match) or j reaches the end of t (no match).
- s is a subsequence of t exactly when i reaches the end of s.
Walk through the code
Same walkthrough, now with the code. Press Next to move one step and watch which lines run.
0a
1h
2b
3g
4d
5c
Statusinit
i=0 (looking for 'a') and j=0 ('a') — match. i advances to 1.
What happens in this step
i = 0 (need 'a'), j = 0 (value 'a') t[j] == s[i] Match — i advances to 1, now looking for s[1]='b'.
Step 1 of 4
Solution
function isSubsequence(s, t) {
if (s.length === 0) {
return true;
}
let i = 0;
for (let j = 0; j < t.length; j++) {
if (s[i] === t[j]) {
i++;
if (i === s.length) {
return true;
}
}
}
return i === s.length;
}- Time
- O(n)
- Space
- O(1)
Test cases
| Input | Expected | Covers |
|---|---|---|
s = "abc", t = "ahbgdc" | true | example from the docstring |
s = "", t = "ahbgdc" | true | empty s is trivially a subsequence of anything |
s = "abcde", t = "ab" | false | s is longer than t, so it cannot fit |
s = "abc", t = "abc" | true | s and t are identical |
s = "axc", t = "ahbgdc" | false | a middle character of s never appears in the remaining part of t |
s = "a", t = "" | false | empty t cannot contain a non-empty s |
s = "a", t = "a" | true | smallest non-trivial matching case, single characters |