Longest Common Subsequence
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
0 ≤ text1.length, text2.length ≤ 12 - ◆
text1 and text2 consist only of lowercase English letters
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursive Without Memoization
BruteAt every pair of positions (i, j) there are only two live moves. When the current tail characters agree, that character must be part of an optimal common subsequence, so lock it in and shrink both strings by one. When they disagree, at least one of the two tail characters can be dropped without losing the best answer — but which one is unknown up front, so both possibilities are tried and the larger result kept. The catch is that the same (i, j) pair gets reached through many different sequences of drops, and each time it is solved completely from scratch again.
O(2ⁿ⁺ᵐ)O(n+m)1class Solution {
2 private String text1, text2;
3
4 public int longestCommonSubsequence(String text1, String text2) {
5 this.text1 = text1;
6 this.text2 = text2;
7 return solve(text1.length(), text2.length());
8 }
9
10 private int solve(int i, int j) {
11 if (i == 0 || j == 0) return 0;
12 if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
13 return 1 + solve(i - 1, j - 1);
14 }
15 return Math.max(solve(i - 1, j), solve(i, j - 1));
16 }
17}Optimal — Bottom-Up 2D DP
OptimalBuild a table dp[i][j] holding the answer for the first i characters of text1 against the first j characters of text2, filling it in order from the smallest prefixes up. Every cell needs only the three cells directly above, to the left, and diagonally above-left of it, so each one is computed exactly once instead of being re-derived on demand through recursion. The very last cell, using the full length of both strings, is the final answer.
O(n·m)O(n·m)1class Solution {
2 public int longestCommonSubsequence(String text1, String text2) {
3 int n = text1.length(), m = text2.length();
4 int[][] dp = new int[n + 1][m + 1];
5 for (int i = 1; i <= n; i++) {
6 for (int j = 1; j <= m; j++) {
7 if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
8 dp[i][j] = dp[i - 1][j - 1] + 1;
9 } else {
10 dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
11 }
12 }
13 }
14 return dp[n][m];
15 }
16}