Problem
Submissions

Solution: Longest Common Subsequence

Statement

Naive approach

A naive approach would be to compare the characters of both strings based on the following rules:

  • If the current characters of both strings match, we move one position ahead in both strings.

  • If the current characters of both strings do not match, we recursively calculate the maximum length of moving one character forward in any one of the two strings i.e., we check if moving a character forward in either the first string or the second will give us a longer subsequence.

  • If we reach the end of either of the two strings, we return 00.

The time complexity of the naive approach is O(2m+n)O(2^{m+n}), where mm and nn are the lengths of the two strings, respectively. The space complexity of this approach is O(n+m)O(n + m).

Optimized approach using dynamic programming

We are going to solve this problem with the help of the top-down approach of dynamic programming. The top-down solution, commonly known as the memoization technique, is an enhancement of the recursive solution. It overcomes the problem of calculating redundant solutions over and over again by storing them in an array. In the recursive approach, the following two variables kept changing:

  • The index, i, used to keep track of the current character in str1.

  • The index, j, used to keep track of the current character in str2.

We will use a 2D table, dp, with nn rows and mm columns to store the result at any given state. nn represents the length of str1 and and mm represents the length of str2. At any later time, if we encounter the same subproblem, we can return the stored result from the table with an O(1)O(1) lookup instead of recalculating that subproblem.

Let’s look at the following illustration to get a better understanding of the solution:

Problem
Submissions

Solution: Longest Common Subsequence

Statement

Naive approach

A naive approach would be to compare the characters of both strings based on the following rules:

  • If the current characters of both strings match, we move one position ahead in both strings.

  • If the current characters of both strings do not match, we recursively calculate the maximum length of moving one character forward in any one of the two strings i.e., we check if moving a character forward in either the first string or the second will give us a longer subsequence.

  • If we reach the end of either of the two strings, we return 00.

The time complexity of the naive approach is O(2m+n)O(2^{m+n}), where mm and nn are the lengths of the two strings, respectively. The space complexity of this approach is O(n+m)O(n + m).

Optimized approach using dynamic programming

We are going to solve this problem with the help of the top-down approach of dynamic programming. The top-down solution, commonly known as the memoization technique, is an enhancement of the recursive solution. It overcomes the problem of calculating redundant solutions over and over again by storing them in an array. In the recursive approach, the following two variables kept changing:

  • The index, i, used to keep track of the current character in str1.

  • The index, j, used to keep track of the current character in str2.

We will use a 2D table, dp, with nn rows and mm columns to store the result at any given state. nn represents the length of str1 and and mm represents the length of str2. At any later time, if we encounter the same subproblem, we can return the stored result from the table with an O(1)O(1) lookup instead of recalculating that subproblem.

Let’s look at the following illustration to get a better understanding of the solution: