Skip to content

Commit 74e7606

Browse files
committed
Add longest_common_subsequence algorithm to strings
1 parent f662b63 commit 74e7606

1 file changed

Lines changed: 51 additions & 0 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
def longest_common_subsequence(s1: str, s2: str) -> str:
2+
"""
3+
Returns the Longest Common Subsequence (LCS) of two strings.
4+
5+
The LCS is the longest sequence of characters that appear in both strings in the
6+
same relative order, but not necessarily contiguously.
7+
8+
Args:
9+
s1: The first string.
10+
s2: The second string.
11+
12+
Returns:
13+
The longest common subsequence as a string.
14+
15+
Example:
16+
>>> longest_common_subsequence("ABCBDAB", "BDCAB")
17+
'BCAB'
18+
>>> longest_common_subsequence("XMJYAUZ", "MZJAWXU")
19+
'MJAU'
20+
"""
21+
m, n = len(s1), len(s2)
22+
dp = [[0] * (n + 1) for _ in range(m + 1)]
23+
24+
# Fill DP table
25+
for i in range(m):
26+
for j in range(n):
27+
if s1[i] == s2[j]:
28+
dp[i + 1][j + 1] = dp[i][j] + 1
29+
else:
30+
dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j])
31+
32+
# Backtrack to get LCS string
33+
i, j = m, n
34+
lcs_chars = []
35+
while i > 0 and j > 0:
36+
if s1[i - 1] == s2[j - 1]:
37+
lcs_chars.append(s1[i - 1])
38+
i -= 1
39+
j -= 1
40+
elif dp[i - 1][j] >= dp[i][j - 1]:
41+
i -= 1
42+
else:
43+
j -= 1
44+
45+
return "".join(reversed(lcs_chars))
46+
47+
48+
if __name__ == "__main__":
49+
# Basic tests
50+
print(longest_common_subsequence("ABCBDAB", "BDCAB")) # BCAB
51+
print(longest_common_subsequence("XMJYAUZ", "MZJAWXU")) # MJAU

0 commit comments

Comments
 (0)