392. Is Subsequence - Detailed Explanation

Free Coding Questions Catalog
Boost your coding skills with our essential coding questions catalog. Take a step towards a better tech career now!

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 no) characters from the original string without changing the relative order of the remaining characters.

Definition:

  • Subsequence: A string s is a subsequence of t if you can remove zero or more characters from t to get s while preserving the order of the characters.

Examples:

  • Example 1:

    • Input: s = "abc", t = "ahbgdc"
    • Output: true
    • Explanation:
      The characters "a", "b", "c" appear in "ahbgdc" in the same order (i.e. "a", then "b", then "c").
  • 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".

Constraints:

  • 0 ≤ s.length ≤ 100
  • 0 ≤ t.length ≤ 10⁴
  • Both s and t consist of lowercase English letters.

Hints

  • Hint 1:
    Use two pointers—one for s and one for t. Traverse t and check if the current character matches the current character in s. If it does, move the pointer in s.

  • Hint 2:
    Once you reach the end of s, you know that all characters of s have been found in order in t.

  • Hint 3:
    If you finish traversing t and haven’t advanced the pointer in s to the end, then s is not a subsequence of t.

Approaches

Two-Pointer Approach (Optimal)

Idea:

  • Use one pointer (i) to iterate over s and another pointer (j) to iterate over t.
  • For each character in t, check if it matches the current character in s (i.e. s[i]).
  • If they match, move the pointer in s forward.
  • Continue until either pointer reaches the end of its respective string.
  • If the pointer for s reaches the end (i.e. i == s.length), then s is a subsequence of t.

Steps:

  1. Initialize two pointers: i = 0 for s and j = 0 for t.
  2. While both i < s.length and j < t.length:
    • If s[i] == t[j], increment i (found a matching character).
    • Always increment j to move to the next character in t.
  3. After the loop, check if i is equal to s.length. If yes, return true; otherwise, return false.

Idea:

  • Preprocess t to record the indices of each character.
  • For each query string s, use binary search to find whether each character in s appears in t after the previous character’s index.
  • This method is useful if you have multiple queries against the same string t.

Note:
For a single query, the two-pointer approach is more straightforward and efficient.

Detailed Walkthrough (Two-Pointer Approach)

Let’s consider the example where s = "abc" and t = "ahbgdc".

  1. Initialization:

    • i = 0 (points to 'a' in s)
    • j = 0 (points to 'a' in t)
  2. Iteration:

    • Step 1: Compare s[0] ('a') with t[0] ('a'):
      • They match → increment i to 1.
      • Increment j to 1.
    • Step 2: Now, compare s[1] ('b') with t[1] ('h'):
      • No match → keep i at 1, increment j to 2.
    • Step 3: Compare s[1] ('b') with t[2] ('b'):
      • They match → increment i to 2, increment j to 3.
    • Step 4: Compare s[2] ('c') with t[3] ('g'):
      • No match → keep i at 2, increment j to 4.
    • Step 5: Compare s[2] ('c') with t[4] ('d'):
      • No match → keep i at 2, increment j to 5.
    • Step 6: Compare s[2] ('c') with t[5] ('c'):
      • They match → increment i to 3, increment j to 6.
  3. Conclusion:

    • Now i == s.length (3 == 3), so all characters of s were found in t in order.
    • Return true.

Code Implementation

Python Code

Python3
Python3

. . . .

Java Code

Java
Java

. . . .

Complexity Analysis

  • Time Complexity:
    O(n + m), where n is the length of string s and m is the length of string t.
    In the worst case, every character of t is checked, and each character of s is compared at most once.

  • Space Complexity:
    O(1), since we use only two integer pointers regardless of the input size.

Additional Sections

Common Mistakes

  • Not Advancing the Pointer in t:
    Failing to increment the j pointer in t on every iteration can lead to an infinite loop.

  • Incorrect Edge Case Handling:
    Not checking cases where s is empty (which should return true) or when t is empty (except when s is also empty).

Edge Cases

  • Empty s:
    An empty string is considered a subsequence of any string.

  • Empty t:
    If t is empty and s is not, then s cannot be a subsequence of t.

  • Identical Strings:
    If s equals t, the answer is true.

  • Variations:

    • Longest Common Subsequence (LCS): A related problem where the goal is to find the longest subsequence common to two strings.
    • Subsequence Counting: Count the number of times a subsequence appears in a given string.
  • Related Problems for Further Practice:

TAGS
leetcode
CONTRIBUTOR
Design Gurus Team
-

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Explore Answers
How do I nail my interview?
How to write a portfolio for an interview?
What is the interview process for Coinbase engineering?
Related Courses
Image
Grokking the Coding Interview: Patterns for Coding Questions
Grokking the Coding Interview Patterns in Java, Python, JS, C++, C#, and Go. The most comprehensive course with 476 Lessons.
Image
Grokking Modern AI Fundamentals
Master the fundamentals of AI today to lead the tech revolution of tomorrow.
Image
Grokking Data Structures & Algorithms for Coding Interviews
Unlock Coding Interview Success: Dive Deep into Data Structures and Algorithms.
Image
One-Stop Portal For Tech Interviews.
Copyright © 2025 Design Gurus, LLC. All rights reserved.
;