Day 2 :
Is it a subsequence ?
Problem Description
You are given a string s and a string t. Check whether s is a subsequence of t ?
Problem Description
You are given a string s and a string t. Check whether s is a subsequence of t ?
What is subsequence?
Problem Description
In typical definition it means
A subsequence is a sequence generated froma string after deleting some characters of string without changing the order of remaining string characters
Example 1 :
String 1 : abc
String 2 : ahjbnlc
Problem Description
Example 1 :
String 1 : abc
String 2 : ahjbnlc
Problem Description
Example 1 :
String 1 : abc
String 2 : ahjbnlc
| a | h | j | b | n | l | c |
|---|
Problem Description
Example 1 :
String 1 : abc
String 2 : ahjbnlc
| a | b | c |
|---|
Problem Description
Example 1 :
String 1 : abc
String 2 : ahjbnlc
| a | b | c |
|---|
Problem Description
Example 1 :
String 1 : abc
String 2 : ahjbnlc
| a | b | c |
|---|
Now we understood what exactly subsequence means...!!!!! :-)
Now coming back to the problem guys!!!!
Given two string we need to check wether string 's' is a subsequence of string 't'.
Again we are going to develop the thinking process towards a problem... that means...
Again we are going to develop the thinking process towards a problem... that means...
1. A Recursive approach
2. An iterative approach
Now let us discuss the recursive approach..!!!!
Let us consider two strings
s = "abc", t = "ahbgdc"
Now let us discuss the recursive approach..!!!!
s = "abc", t = "ahbgdc"
Will try every possible case by removing characters from string t.
Now let us discuss the recursive approach..!!!!
s = "abc", t = "ahbgdc"
check whether "ahbgdc" matches "abc"
we have reached at n = 3
If the answer is no, recurse further.
Now let us discuss the recursive approach..!!!!
s = "abc", t = "ahbgdc"
check whether "ahbgdc" matches "abc"
we have reached at n = 3
If the answer is no, recurse further.
remove 'a'
Don't remove 'a'
"hbgdc"
"ahbgdc"
Now let us discuss the recursive approach..!!!!
s = "abc", t = "ahbgdc"
check whether "ahbgdc" matches "abc"
we have reached at n = 3
If the answer is no, recurse further.
remove 'a'
Don't remove 'a'
"hbgdc"
"ahbgdc"
remove 'h'
Don't remove 'h'
"bgdc"
"hbgdc"
Now let us discuss the recursive approach..!!!!
s = "abc", t = "ahbgdc"
we have reached at n = 3
check whether "ahbgdc" matches "abc"
remove 'a'
Don't remove 'a'
"hbgdc"
"ahbgdc"
remove 'h'
Don't remove 'h'
"bgdc"
"hbgdc"
remove 'h'
Don't remove 'h'
"abgdc"
"ahbgdc"
we have reached at n = 3
Time Complexity
Time Complexity of this recursive solution in which we are trying every possible subsequence of string t in O(2^n)
we have reached at n = 3
Time Complexity
Time Complexity of this recursive solution in which we are trying every possible subsequence of string t in O(2^n)
But How?
Let's See
we have reached at n = 3
Time Complexity
Time Complexity of this recursive solution in which we are trying every possible subsequence of string t in O(2^n)
But How?
Consider a binary string of 1's of the same length as that of t, Now consider removing a character from t as 0.
Now If I ask you how many ways are there in which you can replace the 1's with zero?
What would be your answer?
Isn't it
Isn't it
| 1 | 1 | 1 | 1 | 1 | 1 |
|---|
Isn't it
| 1 | 1 | 1 | 1 | 1 | 1 |
|---|
2
2
2
2
2
2
Now we have understood that we can't use that because of that exponential complexity.
Let's take our tree back to understand where we can reduce the complexity further.
Let's take our tree back to understand where we can reduce the complexity further.
check whether "ahbgdc" matches "abc"
remove 'a'
Don't remove 'a'
"hbgdc"
"ahbgdc"
remove 'h'
Don't remove 'h'
"bgdc"
"hbgdc"
remove 'h'
Don't remove 'h'
"abgdc"
"ahbgdc"
Let's take our tree back to understand where we can reduce the complexity further.
check whether "ahbgdc" matches "abc"
remove 'a'
"hbgdc"
remove 'h'
Don't remove 'h'
"bgdc"
"hbgdc"
remove 'h'
Don't remove 'h'
"abgdc"
"ahbgdc"
Don't remove 'a'
"ahbgdc"
Let's take our tree back to understand where we can reduce the complexity further.
check whether "ahbgdc" matches "abc"
remove 'a'
Don't remove 'a'
"hbgdc"
"ahbgdc"
remove 'h'
Don't remove 'h'
"bgdc"
"hbgdc"
remove 'h'
Don't remove 'h'
"abgdc"
"ahbgdc"
Let's take our tree back to understand where we can reduce the complexity further.
check whether "ahbgdc" matches "abc"
remove 'a'
Don't remove 'a'
"hbgdc"
"ahbgdc"
remove 'h'
Don't remove 'h'
"bgdc"
"hbgdc"
remove 'h'
Don't remove 'h'
"abgdc"
"ahbgdc"
remove 'g'
"abdc"
Don't remove 'ag'
"abgdc"
check whether "ahbgdc" matches "abc"
remove 'a'
Don't remove 'a'
"hbgdc"
"ahbgdc"
remove 'h'
Don't remove 'h'
"bgdc"
"hbgdc"
remove 'h'
Don't remove 'h'
"abgdc"
"ahbgdc"
remove 'g'
"abdc"
Don't remove 'g'
"abgdc"
remove 'd'
"abc"
"abdc"
Don't remove 'd'
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}isSubsequence(s,t,0,0)
| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
isSubsequence(s,t,0,0)
isSubsequence(s,t,1,1)
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
isSubsequence(s,t,0,0)
isSubsequence(s,t,1,1)
isSubsequence(s,t,1,2)
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
isSubsequence(s,t,0,0)
isSubsequence(s,t,1,1)
isSubsequence(s,t,1,2)
isSubsequence(s,t,2,3)
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
isSubsequence(s,t,0,0)
isSubsequence(s,t,1,1)
isSubsequence(s,t,1,2)
isSubsequence(s,t,2,3)
isSubsequence(s,t,2,4)
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
isSubsequence(s,t,0,0)
isSubsequence(s,t,1,1)
isSubsequence(s,t,1,2)
isSubsequence(s,t,2,3)
isSubsequence(s,t,2,4)
isSubsequence(s,t,2,5)
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
isSubsequence(s,t,0,0)
isSubsequence(s,t,1,1)
isSubsequence(s,t,1,2)
isSubsequence(s,t,2,3)
isSubsequence(s,t,2,4)
isSubsequence(s,t,2,5)
isSubsequence(s,t,3,6)
Let's Code this Recursive Approach
bool isSubsequence(string s,string t, int i, int j)
{
//Base Condition for recursion
//now if we have reached i = s.size()
//that means all the characters in s are matched so we return true.
if (i == s.size())
return true;
//now this will be checked only if
//first fails that mean we have reached to
//the end of string t and string s still have charachters to be matched
//in that case we will return false
if (j == t.size())
return false;
if (t[j] == s[i])
return isSubsequence(s, t, i+1, j+1);
return isSubsequence(s, t, i, j+1);
}| a | h | b | g | d | c |
|---|
| a | b | c |
|---|
String s
String t
isSubsequence(s,t,0,0)
isSubsequence(s,t,1,1)
isSubsequence(s,t,1,2)
isSubsequence(s,t,2,3)
isSubsequence(s,t,2,4)
isSubsequence(s,t,2,5)
isSubsequence(s,t,3,6)
True
True
True
True
True
True
Time Complexity
O(m)
We have Just reduced Complexity from O(2^n) to a linear O(m).
Let's Try a DP iterative Solution.
Let's try to build the intuition for DP Solution.
s = "abc"
t = "ahbgdc"
What if s only contains "a" that means s = "a" and t = "ahbgdc".
| 0 | 1 | 1 | 1 | 1 | 1 | 1 |
|---|
res 1
Let's Try a DP iterative Solution.
Let's try to build the intuition for DP Solution.
s = "abc"
t = "ahbgdc"
| 0 | 1 | 1 | 1 | 1 | 1 | 1 |
|---|
Now extend s
s = "ab"
t = "ahbgdc"
res 1
res 2
| 0 | 0 | 0 | 1 | 1 | 1 | 1 |
|---|
Let's Try a DP iterative Solution.
Let's try to build the intuition for DP Solution.
| 0 | 1 | 1 | 1 | 1 | 1 | 1 |
|---|
Now extend s
s = "abc"
t = "ahbgdc"
res 1
res 2
| 0 | 0 | 1 | 1 | 1 | 1 | 1 |
|---|
res 3
| 0 | 0 | 0 | 0 | 0 | 0 | 1 |
|---|
bool isSubsequence(string s, string t) {
int n = s.size();
int m = t.size();
vector<vector<bool>> dp(n+1, vector <bool>(m+1,0));
dp[0][0] = true;
for (int i = 1;i <= n;i++)
dp[i][0] = false;
for (int j = 1;j <= m;j++)
dp[0][j] = true;
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= m;j++)
{
if (s[i-1] == t[j-1])
dp[i][j] = dp[i-1][j-1];
else
dp[i][j] = dp[i][j-1];
}
}
return dp[n][m];
}So that's It for Day 2
So that's It for Day 2
Concepts that we have learnt
So that's It for Day 1
We have taken a very first step in Dynamic Programming.
Concepts that we have learnt
1. Recursive Approach.
So that's It for Day 1
We have taken a very first step in Dynamic Programming.
Concepts that we have learnt
1. Recursive Approach.
2. Identifying unwanted computation and reduce complexity in recursion solution.
So that's It for Day 1
We have taken a very first step in Dynamic Programming.
Concepts that we have learnt
1. Overlapping Subproblems in DP
2. Identifying unwanted computation and reduce complexity in recursion solution.
3. Bottom-Up Approach in DP with 2 D matrix.
So that's It for Day 1
We have taken a very first step in Dynamic Programming.
Concepts that we have learnt
1. Overlapping Subproblems in DP
2. Top-down Approach in DP
3. Bottom-Up Approach in DP with 2 D matrix.
Still, Have any Doubts???
Still, Have any Doubts???
Comment it You will get a reply.
OR
Send your doubt to email provided in description.