Problem Statement:
Given two strings text1
 and text2
, return the length of their longest common subsequence. If there is no common subsequence, return 0
.
A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.
- For example,Â
"ace"
 is a subsequence ofÂ"abcde"
. A common subsequence of two strings is a subsequence that is common to both strings.
Example 1:
Input: text1 = “abcde”, text2 = “ace”
Output: 3
Explanation: The longest common subsequence is “ace” and its length is 3.
Example 2: Input: text1 = “abc”, text2 = “abc” Output: 3 Explanation: The longest common subsequence is “abc” and its length is 3.
Example 3: Input: text1 = “abc”, text2 = “def” Output: 0 Explanation: There is no such common subsequence, so the result is 0.
Solution:
Recursion and Memoized:
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int n1 = text1.length();
int n2 = text2.length();
int[][] dp = new int[n1 + 1][n2 + 1];
for(int[] row: dp){
Arrays.fill(row, -1);
}
return longestCommonSubsequence(text1, text2, 0, 0, dp);
}
public int longestCommonSubsequence(String t1, String t2, int idx1, int idx2, int[][] dp){
if(idx1 >= t1.length() || idx2 >= t2.length()){
return 0;
}
if(dp[idx1][idx2] != -1){
return dp[idx1][idx2];
}
if(t1.charAt(idx1) == t2.charAt(idx2)){
return dp[idx1][idx2] = 1 + longestCommonSubsequence(t1, t2, idx1 + 1, idx2 + 1, dp);
}
return dp[idx1][idx2] = Math.max(
longestCommonSubsequence(t1, t2, idx1 + 1, idx2, dp),
longestCommonSubsequence(t1, t2, idx1, idx2 + 1, dp)
);
}
}
Tabulation:
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int n1 = text1.length();
int n2 = text2.length();
int[][] dp = new int[n1 + 1][n2 + 1];
for(int i = 1; i <= n1; i++){
for(int j = 1; j <= n2; j++){
if(text1.charAt(i - 1) == text2.charAt(j - 1)){
dp[i][j] = 1 + dp[i - 1][j - 1];
} else{
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[n1][n2];
}
}
Space Optimized
class Solution {
public int longestCommonSubsequence(String text1, String text2) {
int n1 = text1.length();
int n2 = text2.length();
int[] prev = new int[n2 + 1];
int[] curr = new int[n2 + 1];
Arrays.fill(prev, 0);
curr[0] = 0;
for(int i = 1; i <= n1; i++){
//fill the rows of curr
for(int j = 1; j <= n2; j++){
if(text1.charAt(i - 1) == text2.charAt(j - 1)){
curr[j] = 1 + prev[j - 1];
} else{
curr[j] = Math.max(prev[j], curr[j - 1]);
}
}
prev = curr.clone();
}
return prev[n2];
}
}