
Problem Statement
In this problem, you are provided with two strings: s
and t
. The task is to determine whether the string s
is a subsequence of the string t
. The function should return true
if s
is a subsequence of t
, and false
otherwise.
To clarify, a subsequence is derived from another string by deleting some or none of the characters without rearranging the order of the remaining characters. For instance, "ace"
is a subsequence of "abcde"
because you can remove "b" and "d" from "abcde"
to form "ace"
. However, "aec"
is not a subsequence of "abcde"
since the letters are not in the same order in both strings.
Examples
Example 1
Input:
s = "abc", t = "ahbgdc"
Output:
true
Example 2
Input:
s = "axc", t = "ahbgdc"
Output:
false
Constraints
0 <= s.length <= 100
0 <= t.length <= 104
s
andt
consist only of lowercase English letters.
Approach and Intuition
To solve the problem of determining if s
is a subsequence of t
, the key is to check each character of s
and ensure it appears in t
in the same relative order. If any character in s
fails this condition, the function will return false
. Below is a step-by-step approach to realize the solution:
- Initialize a
pointer
for strings
at position 0. - Iterate through each character of string
t
.- For each character in
t
, compare it with the character at the currentpointer
position ofs
. - If they match:
- Move the
pointer
forward ins
(i.e., increment thepointer
). - If the
pointer
equals the length ofs
, it means all characters ofs
have been matched int
in order, so returntrue
.
- Move the
- For each character in
- If the end of
t
is reached and there are characters ins
that haven't been matched, returnfalse
.
This approach ensures a linear time complexity relative to the length of t
, making it efficient given the constraint where the length of t
can be up to 10,000. Each character of t
is processed in sequence, and the process halts early if s
is fully matched or continues to the end of t
if needed.
Solutions
- Java
- Python
class Solution {
public boolean sequenceMatcher(String str1, String str2) {
Integer len1 = str1.length(), len2 = str2.length();
if (len1 == 0)
return true;
int[][] matchTable = new int[len1 + 1][len2 + 1];
for (int j = 1; j <= len2; ++j) {
for (int i = 1; i <= len1; ++i) {
if (str1.charAt(i - 1) == str2.charAt(j - 1))
matchTable[i][j] = matchTable[i - 1][j - 1] + 1;
else
matchTable[i][j] = Math.max(matchTable[i][j - 1], matchTable[i - 1][j]);
}
if (matchTable[len1][j] == len1)
return true;
}
return false;
}
}
The provided Java solution addresses the problem of determining whether one string (str1
) is a subsequence of another string (str2
). The method sequenceMatcher
accomplishes this by employing a dynamic programming approach using a 2D array, matchTable
, to store the lengths of matching subsequences found during the iteration through both strings.
Here's how the solution works:
- Initiate
matchTable
wherematchTable[i][j]
represents the length of the longest subsequence common tostr1
up to i andstr2
up to j. - Iterate through each character in
str2
(outer loop) and for each character ofstr2
, iterate through each character ofstr1
(inner loop). - If characters from both strings match, the value in the table is derived from the top-left diagonal cell incremented by one. This indicates the continuation of an existing subsequence.
- If there's no match, the cell's value is the maximum of either the cell directly above or the cell to the left, representing the longest subsequence found so far without including the current character.
- After updating the table through each character of
str2
, check if the subsequence having the length ofstr1
has been found by looking at the last cell of the current column ofstr2
. - If
str1
is indeed a subsequence at any point during the traversal ofstr2
, return true. - If after completing the traversal, no such subsequence is identified, return false.
This method efficiently determines the relationship between the two strings, optimizing checks and balances through dynamic programming, and provides an immediate exit upon confirmation that a subsequence exists, making it computationally efficient for varying lengths of input strings.
class Solution:
def isSubsequence(self, sub: str, main: str) -> bool:
len_sub, len_main = len(sub), len(main)
if len_sub == 0:
return True
dp_table = [[0] * (len_main + 1) for _ in range(len_sub + 1)]
for i in range(1, len_main + 1):
for j in range(1, len_sub + 1):
if sub[j - 1] == main[i - 1]:
dp_table[j][i] = dp_table[j - 1][i - 1] + 1
else:
dp_table[j][i] = max(dp_table[j][i - 1], dp_table[j - 1][i])
if dp_table[len_sub][i] == len_sub:
return True
return False
The solution provided in Python addresses the problem of checking if one string is a subsequence of another. The function isSubsequence
takes two strings, sub
and main
, and determines if sub
is a subsequence within main
.
The initial check in the solution handles the case where the subsequence is empty, immediately returning True
since an empty sequence is trivially a subsequence of any string.
A dynamic programming approach is used, establishing a 2D list dp_table
where dp_table[j][i]
will hold the length of longest common subsequence of sub[0:j]
and main[0:i]
.
- A nested loop iterates through both
sub
andmain
.- If characters from
sub
andmain
match, the value in the DP table is updated to carry over the length from the previous matched position incremented by one. - If no match occurs, the function carries forward the maximum subsequence length found so far either from skipping a character in
sub
ormain
.
- If characters from
The function concludes if the value at dp_table[len_sub][i]
is equal to len_sub
at any column i
, signifying all characters of sub
have been matched in sequence within main
.
If the end of main
is reached and sub
has not been fully matched, False
is returned. This approach efficiently checks the subsequence condition with the help of dynamic programming, ensuring all possible subsequences of main
are explored for a potential complete match with sub
.
No comments yet.