Is Subsequence

EasyStrings · Two Pointers🧩 String ManipulationLeetCode #392 ↗Updated

Problem

Given strings s and t, decide whether s can be obtained from t by deleting some (possibly zero) characters without reordering the rest — i.e. whether s is a subsequence of t.
Inputs="abc", t="ahbgdc"Outputtrue
Inputs="axc", t="ahbgdc"Outputfalse

0 ≤ |s| ≤ 100  ·  0 ≤ |t| ≤ 104  ·  lowercase letters  ·  Follow-up: billions of s queries against one t.

Try it yourself

Java
class Solution {
    public boolean isSubsequence(String s, String t) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Matching greedily is safe: using the earliest occurrence of each s character in t leaves the most room for the remaining characters.
PatternString Manipulation

Instinct Reading, comparing or rebuilding text character by character? Walk indices on a char[] and build output with a StringBuilder, never with + in a loop.

Memory hack Chars in an array, pointers on the ends, builder at the back - strings are just arrays wearing a costume.

Open the String Manipulation guide →

Approaches

Brute ForceLCS Dynamic Programming

Time O(n·m)Space O(n·m)

s is a subsequence of t iff LCS(s, t) == |s|. Fill the classic table: on a match extend the diagonal, otherwise take the max of skipping a character from either string.

Java
public boolean isSubsequence(String s, String t) {
    int n = s.length(), m = t.length();
    int[][] dp = new int[n + 1][m + 1];
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (s.charAt(i - 1) == t.charAt(j - 1)) dp[i][j] = dp[i - 1][j - 1] + 1;
            else dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
        }
    }
    return dp[n][m] == n;
}

Correct but heavy — solves a harder problem than needed.

At a glance

LevelApproachTimeSpace
Brute ForceLCS Dynamic ProgrammingO(n·m)O(n·m)
BetterTwo Pointers (Greedy Scan)O(n + m)O(1)
OptimalIndex Lists + Binary Search (Follow-up)O(m) once + O(n log m)/queryO(m)
Common pitfalls
  • Advancing the s pointer on a mismatch — only t's pointer always moves.
  • Forgetting that an empty s is always a subsequence (return true).
  • Confusing subsequence with substring — characters need not be contiguous.
Interview tips
  • Justify the greedy: earliest match never hurts later matches.
  • Bring up the follow-up yourself and sketch the binary-search preprocessing.
  • Note the DP view links to LCS / Edit Distance if asked to generalise.
Pattern
Two pointers across two sequences → match one sequence inside another in order.
My notes saved in this browser