Dynamic Programming
Subproblem
Say input strings are and
. Let
be the length of the longest common subsequence between the pair of prefixes
and
.
is the solution.
Order
Subproblems on a -grid and row-wise processing gives a topological ordering.
Time: , space:
.
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
x, y = text1, text2
m, n = len(x), len(y)
dp = [
[float('-inf')]*(n+1) for _ in range(m+1)
]
for c in range(n+1):
dp[0][c] = 0
for r in range(m+1):
dp[r][0] = 0
for r in range(1, m+1):
for c in range(1, n+1):
i, j = r-1, c-1
if x[i] == y[j]:
dp[r][c] = 1 + dp[r-1][c-1]
else:
dp[r][c] = max( dp[r-1][c], dp[r][c-1] )
return dp[m][n]
A subproblem depends on the subproblems that are on the same row or on the previous row. So, we keep track of just two rows and reuse.
Time: , space:
.
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
x, y = text1, text2
m, n = len(x), len(y)
dp = [
[float('-inf')]*(n+1) for _ in range(2)
]
for c in range(n+1):
dp[0][c] = 0
dp[0][0], dp[1][0] = 0, 0
prev_row, curr_row = 0, 1
for r in range(1, m+1):
for c in range(1, n+1):
i, j = r-1, c-1
if x[i] == y[j]:
dp[curr_row][c] = 1 + dp[prev_row][c-1]
else:
dp[curr_row][c] = max( dp[prev_row][c], dp[curr_row][c-1] )
prev_row, curr_row = curr_row, prev_row
return dp[prev_row][n]
Leave a comment