Leetcode 392. Is Subsequence
Problem Explanation:
This problem is about checking if a string s
is a subsequence of another string t
. Both strings contain only lowercase English letters. The string t
can be very long, up to around 500,000 characters, while s
is a short string with no more than 100 characters.
A subsequence of a string is formed by deleting some characters (or none at all) from the original string, but keeping the relative order of the remaining characters.
For example, "ace" is a subsequence of "abcde", but "aec" is not (since the 'c' and 'e' characters in "aec" are not in the same relative order as in "abcde").
So we are asked to return true
if s
is a subsequence of t
, and false
otherwise.
For instance, given s
= "abc", and t
= "ahbgdc". Because we can find "a", "b", and "c" in t
in the correct order, it means "abc" is a subsequence of "ahbgdc", thus we should return true
. On the other hand, with s
= "axc", and t
= "ahbgdc", we won't find "axc" in the same order in t
, thus we should return false
.
Solution Approach:
The solution adopts a simple and effective approach. It loops over each character c
in string t
. If c
is the same as the current character in s
(which is initially the first character and then incremented each time a match is found), it increments the index in s
.
When the index in s
matches the length of s
, it means all characters in s
have been found in t
in the correct order. Therefore, s
is a subsequence of t
and the function returns true
.
If, after going through all the characters in t
, the function has not yet returned true
, it implies that not all characters in s
are found in t
in the correct order. Therefore it returns false
.
Algorithm Walkthrough:
Take s = "abc"
and t = "ahbgdc"
for example.
- Initially the index
i
(fors
) is 0. So the current character ins
is "a". - It starts to loop over each character
c
int
. The firstc
is "a" as well. - Since "a" in
s
matches the "a" int
, it incrementsi
to 1. Now the current character ins
is "b". - It continues to loop over
t
. The next character "h" doesn't match "b", soi
stays 1. The next "b" matches "b" ins
, soi
is incremented to 2. Now the current character ins
is "c". - It repeats the process until the last character "c" in
t
matches "c" ins
. This incrementsi
to 3 which is the length ofs
. Thus,s
is a subsequence oft
. The function returnstrue
.
Python Solution:
1 2python 3class Solution: 4 def isSubsequence(self, s: str, t: str) -> bool: 5 # if s is empty, return True 6 if not s: 7 return True 8 9 i = 0 10 for c in t: 11 # if current character c equals the current character in s 12 if s[i] == c: 13 # increment i 14 i += 1 15 # if all characters in s are found, return True 16 if i == len(s): 17 return True 18 19 # if not all characters are found in s, return False 20 return False
Java Solution:
1 2java 3class Solution { 4 public boolean isSubsequence(String s, String t) { 5 if (s.isEmpty()) { 6 return true; 7 } 8 9 int i = 0; 10 for (char c : t.toCharArray()) { 11 if (s.charAt(i) == c) { 12 i++; 13 if (i == s.length()) { 14 return true; 15 } 16 } 17 } 18 19 return false; 20 } 21}
JavaScript Solution:
1
2javascript
3class Solution {
4 isSubsequence(s, t) {
5 if (s.length === 0) {
6 return true;
7 }
8
9 let i = 0;
10 for (let c of t) {
11 if (s[i] === c) {
12 i++;
13 if (i == s.length) {
14 return true;
15 }
16 }
17 }
18
19 return false;
20 }
21}
22
C++ Solution:
1
2cpp
3class Solution {
4public:
5 bool isSubsequence(string s, string t) {
6 if (s.empty()) {
7 return true;
8 }
9
10 int i = 0;
11 for (char c : t) {
12 if (s[i] == c) {
13 i++;
14 if (i == s.length()) {
15 return true;
16 }
17 }
18 }
19
20 return false;
21 }
22};
C# Solution:
1
2csharp
3public class Solution {
4 public bool IsSubsequence(string s, string t) {
5 if (s.Length == 0) {
6 return true;
7 }
8
9 int i = 0;
10 foreach (char c in t) {
11 if (s[i] == c) {
12 i++;
13 if (i == s.Length) {
14 return true;
15 }
16 }
17 }
18
19 return false;
20 }
21}
Time Complexity:
The time complexity of all solutions is O(n), where n is the length of the string t. This is because in the worst case, the code needs to run through all the characters of the string t.
Since string s is guaranteed to be short (no more than 100 characters), and typically much shorter than t, the operations within the loop are considered constant time. This leaves the time complexity of the entire function as linear with respect to the length of t.
Space Complexity:
The space complexity of all solutions is O(1), or constant time, as there is no additional dynamic space is used. The usage of integer variables, string parameters and boolean return do not grow with the size of the input, they are, therefore, constant.
This makes these algorithms very memory efficient and suitable for problems with large inputs.
Conclusion:
These solutions efficiently solve the problem with straightforward and easy-to-understand code. They all check if a string is a subsequence of another string by looping over the longer string and comparing its characters to those in the shorter string one at a time. They use a pointer in both strings to keep track of the progress and return the result once all characters in the shorter string are found in the correct order or if there are no more characters in the longer string to check. The code is very adaptable and can be easily translated into many other programming languages.
Got a question?ย Ask the Teaching Assistantย anything you don't understand.
Still not clear? Ask in the Forum, ย Discordย orย Submitย the part you don't understand to our editors.