392. Is Subsequence - Detailed Explanation
Problem statement
Description:
Given two strings, s and t, determine whether s is a subsequence of t. A subsequence of a string is formed by deleting some, or none, of the characters from the original string without changing the relative order of the remaining characters.
Definition:
- Subsequence: A string
sis a subsequence oftif you can remove zero or more characters fromtto getswhile preserving the order of the characters.
This question is the plainest instance of the Two Pointers pattern, the technique that moves two indices through the input at different speeds instead of nesting one loop inside another. Here one index advances only on a match, the other advances every step. That pairing shows up repeatedly, as the summary of the most common LeetCode patterns shows.
Examples:
-
Example 1:
- Input:
s = "abc",t = "ahbgdc" - Output:
true - Explanation:
The characters"a","b","c"appear in"ahbgdc"in the same order, that is"a", then"b", then"c".
- Input:
-
Example 2:
- Input:
s = "axc",t = "ahbgdc" - Output:
false - Explanation:
Although"a"and"c"appear in"ahbgdc", the letter"x"does not appear in the correct order to form"axc".
- Input:
Constraints:
- 0 ≤
s.length≤ 100 - 0 ≤
t.length≤ 10⁴ - Both
sandtconsist of lowercase English letters.
Hints
-
Hint 1:
Use two pointers, one forsand one fort. Traversetand check whether the current character matches the current character ins. If it does, move the pointer ins. -
Hint 2:
Once you reach the end ofs, you know that all characters ofshave been found in order int. -
Hint 3:
If you finish traversingtwithout advancing the pointer insto the end, thensis not a subsequence oft.
Approaches
Two pointer approach (optimal)
Idea:
- Use one pointer (
i) to iterate oversand another pointer (j) to iterate overt. - For each character in
t, check whether it matches the current character ins, meanings[i]. - If they match, move the pointer in
sforward. - Continue until either pointer reaches the end of its own string.
- If the pointer for
sreaches the end, meaningi == s.length, thensis a subsequence oft.
Steps:
- Initialize two pointers:
i = 0forsandj = 0fort. - While both
i < s.lengthandj < t.length:- If
s[i] == t[j], incrementi, since you found a matching character. - Always increment
jto move to the next character int.
- If
- After the loop, check whether
iequalss.length. If it does, returntrue. Otherwise, returnfalse.
Dynamic programming or binary search (for multiple queries)
Idea:
- Preprocess
tto record the indices of each character. - For each query string
s, use binary search to find whether each character insappears intafter the index of the previous character. - This method helps when you run many queries against the same string
t.
Note:
For a single query, the two pointer approach is simpler and just as fast.
Detailed walkthrough (two pointer approach)
Consider the example where s = "abc" and t = "ahbgdc".
-
Initialization:
i = 0(points to'a'ins)j = 0(points to'a'int)
-
Iteration:
- Step 1: Compare
s[0]('a') witht[0]('a'):- They match → increment
ito 1. - Increment
jto 1.
- They match → increment
- Step 2: Now compare
s[1]('b') witht[1]('h'):- No match → keep
iat 1, incrementjto 2.
- No match → keep
- Step 3: Compare
s[1]('b') witht[2]('b'):- They match → increment
ito 2, incrementjto 3.
- They match → increment
- Step 4: Compare
s[2]('c') witht[3]('g'):- No match → keep
iat 2, incrementjto 4.
- No match → keep
- Step 5: Compare
s[2]('c') witht[4]('d'):- No match → keep
iat 2, incrementjto 5.
- No match → keep
- Step 6: Compare
s[2]('c') witht[5]('c'):- They match → increment
ito 3, incrementjto 6.
- They match → increment
- Step 1: Compare
-
Conclusion:
- Now
i == s.length(3 == 3), so all characters ofswere found intin order. - Return
true.
- Now
Code implementation
Python code
Java code
Complexity analysis
-
Time Complexity:
O(n + m), where n is the length of stringsand m is the length of stringt.
In the worst case, every character oftis checked, and each character ofsis compared at most once. -
Space Complexity:
O(1), since we use only two integer pointers regardless of the input size.
The same scan, written out line by line, is taught in the Is Subsequence lesson in Grokking the Google Coding Interview.
Additional notes
Common mistakes
-
Not advancing the pointer in
t:
Failing to increment thejpointer inton every iteration can produce an infinite loop. -
Incorrect edge case handling:
Skipping the case wheresis empty, which should returntrue, or the case wheretis empty, which returnstrueonly whensis empty as well.
Edge cases
-
Empty
s:
An empty string counts as a subsequence of any string. -
Empty
t:
Iftis empty andsis not, thenscannot be a subsequence oft. -
Identical strings:
Ifsequalst, the answer istrue.
Alternative variations and related problems
-
Variations:
- Longest Common Subsequence (LCS): A related question that asks for the longest subsequence common to two strings.
- Subsequence Counting: Count the number of times a subsequence appears in a given string.
-
More two pointer practice:
- Two indices that walk toward each other drive Container With Most Water, where the shorter side moves inward each step.
- A write pointer and a read pointer over one array drive Move Zeroes, which is the closest relative of this question.
-
Related problems for further practice:
-
Step up to Longest Increasing Subsequence, a dynamic programming question on sequences.
-
Then try Edit Distance, another string question that compares two sequences.
-

GET YOUR FREE
Coding Questions Catalog

$99

$197

$72