Optimal Grid Path Engine 4 — Problem Statement & Solution Guide
Problem Description
You are given two strings S and T consisting only of lowercase English letters. Determine whether T can be formed by deleting zero or more characters from S without changing the relative order of the remaining characters. In other words, check if T is a subsequence of S. Output "YES" if T is a subsequence of S, otherwise output "NO".
Input: The first line contains the string S. The second line contains the string T.
Output: A single line containing either "YES" or "NO".
DSA Pattern Breakdown
DSA Pattern Breakdown
"Optimal Grid Path Engine 4"
WHY DOES IT MATTER?
Subsequence detection appears in text editors, DNA sequence analysis, and permission‑checking systems where order matters but gaps are allowed; mastering the two‑pointer pattern equips engineers to solve a wide class of linear‑time string problems.
OPTIMIZATION CHALLENGE
The key insight is that you never need to backtrack: once a character of T is matched, the next required character can only appear later in S, allowing a single forward scan with constant auxiliary state.
REAL-WORLD CONNECTION
Think of a train (S) passing through stations; T represents a passenger's itinerary. The passenger can board and alight only at stations in order, skipping intermediate stops—verifying the itinerary is exactly the subsequence check.
During an interview, write the two‑pointer loop first, then immediately discuss edge cases (empty strings, full match) and the O(1) space guarantee; this shows both correctness and efficiency awareness.
COMPLEXITY AT A GLANCE
O(|S| + |T|)O(1)Core Theory — Why This Approach?
The problem of checking whether T is a subsequence of S is a classic instance of the two‑pointer technique applied to strings. By scanning S from left to right while maintaining a pointer into T, we can greedily match characters in order; if we reach the end of T, all its characters appear in S respecting the original order. Naïve solutions that generate all subsets of S or use nested loops to compare each character of T against every possible position in S explode combinatorially (O(2^|S|) or O(|S|·|T|) with repeated rescans) and become infeasible for lengths up to 10^5. The optimal paradigm leverages linear traversal, guaranteeing O(|S| + |T|) time and O(1) extra space, which is optimal because each character must be examined at least once to certify the subsequence property.
Interview Questions on This Problem
Q1How would you modify the algorithm to handle multiple queries asking whether different strings T_i are subsequences of the same S efficiently?
Preprocess S by building a list of positions for each character (a‑z). For each query T_i, iterate its characters and binary‑search the next occurrence in the corresponding list, achieving O(|T_i|·log |S|) per query while keeping O(|S|) preprocessing time and space.
Q2Can you solve the subsequence check in a streaming setting where S arrives character by character and you must answer after each new character?
Maintain a pointer into T; as each character of S streams in, advance the pointer if it matches the current needed character. Once the pointer reaches the end of T, you can immediately answer YES; otherwise, after the stream ends, answer NO. This uses O(1) memory and O(|S|) time.
Q3Why is the two‑pointer method optimal for this problem, and could a dynamic programming approach ever be justified?
Two‑pointer runs in linear time, which matches the lower bound of reading the input once; any DP solution would add unnecessary O(|S|·|T|) time and space. DP is only justified when you need additional information (e.g., count of distinct subsequences) beyond a simple existence check.
Examples
Input
abpcplea apple
Output
YES
Explanation: Traverse S from left to right while matching characters of T: - S[0]=a matches T[0]=a (move to T[1]). - S[1]=b does not match T[1]=p (skip). - S[2]=p matches T[1]=p (move to T[2]). - S[3]=c does not match T[2]=p (skip). - S[4]=p matches T[2]=p (move to T[3]). - S[5]=l matches T[3]=l (move to T[4]). - S[6]=e matches T[4]=e (move to T[5]). All characters of T are matched, so T is a subsequence of S.
Input
abcde aed
Output
NO
Explanation: Scanning S: - Match a at S[0] with T[0]=a (advance T). - Next needed character is e, but S[1]=b, S[2]=c, S[3]=d do not match. - S[4]=e matches e (advance T to d). - No characters remain in S to match the final d, therefore T cannot be obtained as a subsequence.
Input
aaaaa aaa
Output
YES
Explanation: The first three a's of S can be aligned with the three a's of T. After matching the third a, T is fully consumed, confirming it is a subsequence.
Constraints
- 1 <= |S| <= 100000
- 0 <= |T| <= |S|
- S and T contain only lowercase English letters
Optimal Approach & Strategy
Use two pointers: iterate S once, advancing the T pointer only on matches; if T is exhausted, return YES, else NO after the loop.
Brute Force Approach
Generate every possible subsequence of S and compare each to T, or for each character of T scan S from the start each time, leading to exponential or quadratic time.
Verified Code Solutions
function solution(nums) {
return Math.max(...nums);
}class Solution {
public:
int solution(vector<int> nums) {
return *max_element(nums.begin(), nums.end());
}
};class Solution {
public int solution(int[] nums) {
return java.util.Arrays.stream(nums).max().getAsInt();
}
}def solution(nums):
return max(nums)function solution(nums) {
return Math.max(...nums);
}Asked in Top Tech Interviews
Solve in Interative Editor
Ready to test your code? Open our built-in compiler, run custom test suites, and see detailed complexity analysis reports instantly.