◐ Off-By-One · answer catalog

algo-longest-common-subseq

1 answer(s)pythonpython3

return dp[m][n], ''.join(reversed(lcschars))

📦 Source in repository (JSON)

Answer

The longest common subsequence (LCS) problem is solved with classic DP:

  1. 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]).

  2. 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.


Evidence & signatures

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}
Generated from the verified corpus · MIT licensedBack to the catalog