Check If a String Is a Subsequence of Another String
Solve this Problems and t, return true if s is a subsequence of t — meaning every character of s appears in t, in the same relative order, though not necessarily contiguously.
Searching for each character of s across all of t from scratch works, but it repeats work every scan already did. The two-pointerTwo PointerUsing two indices that move through one or more sequences to avoid redundant re-scanning. technique walks both strings forward together in a single pass: advance the pointer into t on every step, and advance the pointer into s only when the current characters match. Neither pointer ever moves backward, so t is scanned exactly once no matter how the characters line up.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
0 ≤ s.length ≤ 100 - ◆
0 ≤ t.length ≤ 10⁴ - ◆
s and t consist of lowercase English letters only
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public boolean isSubsequence(String s, String t) { |
| 3 | int i = 0, j = 0; |
| 4 | while (i < s.length() && j < t.length()) { |
| 5 | if (s.charAt(i) == t.charAt(j)) i++; |
| 6 | j++; |
| 7 | } |
| 8 | return i == s.length(); |
| 9 | } |
| 10 | } |
| 11 |
00Start i (into s) and j (into t) both at 0. j always advances; i advances only on a match.
Approach & Solutions
Brute Force
BruteFor every character of s, scan t from the very beginning looking for the first still-unused occurrence of that character, skipping over indices already claimed by earlier characters. Correct, but every single character of s triggers a fresh scan across t, even though most of the earlier part of t has already been ruled out.
O(n · m)O(1)1class Solution {
2 public boolean isSubsequence(String s, String t) {
3 int usedUpTo = -1;
4 for (int i = 0; i < s.length(); i++) {
5 char c = s.charAt(i);
6 int found = -1;
7 for (int j = 0; j < t.length(); j++) {
8 if (j > usedUpTo && t.charAt(j) == c) { found = j; break; }
9 }
10 if (found == -1) return false;
11 usedUpTo = found;
12 }
13 return true;
14 }
15}Optimal — Two Pointers
OptimalWalk two pointers forward at the same time: one over s, one over t. Advance the t pointer on every step; advance the s pointer only when the characters currently match. Neither pointer ever moves backward, so t is scanned exactly once no matter how it lines up with s. If the s pointer reaches the end, every character of s was matched in order.
O(m)O(1)1class Solution {
2 public boolean isSubsequence(String s, String t) {
3 int i = 0, j = 0;
4 while (i < s.length() && j < t.length()) {
5 if (s.charAt(i) == t.charAt(j)) i++;
6 j++;
7 }
8 return i == s.length();
9 }
10}