Classic LCS 2D solution
class Solution:
def longestCommonSubsequence(self, s1: str, s2: str) -> int:
"""
tc O(M*N) sc O(M*N)
"""
m,n = len(s1), len(s2)
dp = [[0] * (n+1) for _ in range(m+1)]
for i in range(m):
for j in range(n):
if s1[i] == s2[j]:
dp[i+1][j+1] = dp[i][j] + 1
else:
dp[i+1][j+1] = max(dp[i+1][j],dp[i][j+1])
return dp[-1][-1]
1D space optimization
class Solution:
def longestCommonSubsequence(self, s1: str, s2: str) -> int:
m,n = len(s1), len(s2)
"""
tc O(M*N) sc O(min(M,N))
"""
if m < n: return self.longestCommonSubsequence(s2,s1)
dp = [0] * (n+1)
for i in range(m):
pre = 0
for j in range(n):
cur = dp[j+1] # cache current
dp[j+1] = max(pre+(s1[i] == s2[j]), dp[j], cur) # choose the next step optimal 1. chosee current no change 2. choose current pair with previous used number of subsequence 3. not to choose current char with index j => use dp[j]
pre = cur
return dp[n]