|
| 1 | +# [Problem 712: Minimum ASCII Delete Sum for Two Strings](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/description/?envType=daily-question) |
| 2 | + |
| 3 | +## Initial thoughts (stream-of-consciousness) |
| 4 | +This looks like a variant of the Longest Common Subsequence (LCS) problem, but instead of maximizing length we care about ASCII-weighted characters. One way: for any common subsequence, keeping it means deleting all other characters from both strings; the cost is the sum of ASCII values of deleted chars. If I know the ASCII-sum of the largest-weight common subsequence, then the minimal delete cost = total ASCII sum of both strings minus twice that common subsequence sum. So I can reframe as: find the maximum ASCII sum of a common subsequence (a weighted LCS). That suggests a dynamic programming solution similar to LCS, with dp[i][j] representing the maximum ASCII-sum common subsequence using s1[:i] and s2[:j]. |
| 5 | + |
| 6 | +A direct alternative is to compute dp representing minimal delete cost for prefixes, but computing max-weight common subsequence and subtracting is cleaner and symmetric. |
| 7 | + |
| 8 | +## Refining the problem, round 2 thoughts |
| 9 | +- Use DP with complexity O(m * n) where m = len(s1), n = len(s2). This fits constraints up to 1000 (1e6 operations). |
| 10 | +- Memory can be optimized to O(n) using a rolling row because dp[i][j] only depends on dp[i-1][j-1], dp[i-1][j], and dp[i][j-1]. |
| 11 | +- Edge cases: one string empty -> delete all chars of the other string (sum ASCII of that string). The DP handles this naturally. |
| 12 | +- Implementation detail: maintain dp as 1D array of length (n+1). For each i, iterate j from 1..n, keep prev to represent dp[j-1] from previous row. |
| 13 | +- Complexity: Time O(mn), Space O(n). |
| 14 | + |
| 15 | +## Attempted solution(s) |
| 16 | +```python |
| 17 | +class Solution: |
| 18 | + def minimumDeleteSum(self, s1: str, s2: str) -> int: |
| 19 | + m, n = len(s1), len(s2) |
| 20 | + # dp[j] will hold the maximum ASCII-sum of common subsequence |
| 21 | + # for s1[:i] (current row) and s2[:j]. We'll reuse dp for each i. |
| 22 | + dp = [0] * (n + 1) |
| 23 | + |
| 24 | + for i in range(1, m + 1): |
| 25 | + prev = 0 # this will represent dp[j-1] from the previous row |
| 26 | + si = s1[i - 1] |
| 27 | + si_val = ord(si) |
| 28 | + for j in range(1, n + 1): |
| 29 | + temp = dp[j] # store dp[j] from previous row before overwriting |
| 30 | + if si == s2[j - 1]: |
| 31 | + dp[j] = prev + si_val |
| 32 | + else: |
| 33 | + # max of skipping a char from s1 (dp[j] previous row) |
| 34 | + # or skipping a char from s2 (dp[j-1] current row) |
| 35 | + dp[j] = max(dp[j], dp[j - 1]) |
| 36 | + prev = temp |
| 37 | + |
| 38 | + max_common_ascii = dp[n] |
| 39 | + total_ascii = sum(ord(c) for c in s1) + sum(ord(c) for c in s2) |
| 40 | + return total_ascii - 2 * max_common_ascii |
| 41 | +``` |
| 42 | +- Notes: |
| 43 | + - Approach: compute maximum ASCII-sum of a common subsequence using DP (weighted LCS). The minimal deletion cost equals total ASCII sum of both strings minus twice that maximum common-sum. |
| 44 | + - Time complexity: O(m * n), where m = len(s1), n = len(s2). |
| 45 | + - Space complexity: O(n) using a single-row rolling DP array. |
| 46 | + - The implementation uses a classic 1D LCS roll with a `prev` variable to access dp[j-1] from the previous row. This is efficient and straightforward. |
0 commit comments