return dp[m][n], ''.join(reversed(lcschars))
The longest common subsequence (LCS) problem is solved with classic DP:
DP Table: Build an (m+1)×(n+1) table dp where dp[i][j] = length of LCS of s1[:i] and s2[:j]. If characters match, take dp[i-1][j-1] + 1; otherwise take max(dp[i-1][j], dp[i][j-1]).
Backtracking: Walk backwards from dp[m][n]. When chars match, include the char and move diagonally (i-1, j-1). Otherwise move in the direction of the larger DP value. Reverse the collected characters at the end.
Here's the core implementation:
def longest_common_subsequence(s1: str, s2: str):
m, n = len(s1), len(s2)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if s1[i - 1] == s2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
# Backtrack
lcs_chars = []
i, j = m, n
while i > 0 and j > 0:
if s1[i - 1] == s2[j - 1]:
lcs_chars.append(s1[i - 1])
i -= 1
j -= 1
elif dp[i - 1][j] >= dp[i][j - 1]:
i -= 1
else:
j -= 1
return dp[m][n], ''.join(reversed(lcs_chars))
Unicode handling: Python str is Unicode-native. Indexing and comparison work correctly for CJK characters, emoji, accented letters, and any other Unicode code points. No extra encoding/decoding is needed.
The solution was verified against 10 test cases covering:
| Test | Input | Expected | Result |
|------|-------|----------|--------|
| Basic | `("abcde", "ace")` | `(3, "ace")` | Pass |
| No match | `("abc", "def")` | `(0, "")` | Pass |
| Both empty | `("", "")` | `(0, "")` | Pass |
| One empty | `("abc", "")` | `(0, "")` | Pass |
| Full match | `("hello", "hello")` | `(5, "hello")` | Pass |
| Single char match | `("a", "a")` | `(1, "a")` | Pass |
| CJK Unicode | `("你好世界", "你好")` | `(2, "你好")` | Pass |
| Emoji | `("a😊b😢c", "x😊y😢z")` | `(2, "😊😢")` | Pass |
| Repeated chars | `("aaaa", "aa")` | `(2, "aa")` | Pass |
| Classic example | `("AGGTAB", "GXTXAYB")` | `(4, "GTAB")` | Pass |
All tests pass:
```
All tests passed!
```
---{"model": "claude-3.5-sonnet", "problem_class": "algo-longest-common-subseq", "result": "passed", "tests": 10}