Given two strings s1
and s2
, return the lowest ASCII sum of deleted characters to make two strings equal.
Example 1:
Input: s1 = "sea", s2 = "eat"
Output: 231
Explanation: Deleting "s" from "sea" adds the ASCII value of "s" (115) to the sum.
Deleting "t" from "eat" adds 116 to the sum.
At the end, both strings are equal, and 115 + 116 = 231 is the minimum sum possible to achieve this.
Example 2:
Input: s1 = "delete", s2 = "leet"
Output: 403
Explanation: Deleting "dee" from "delete" to turn the string into "let",
adds 100[d] + 101[e] + 101[e] to the sum.
Deleting "e" from "leet" adds 101[e] to the sum.
At the end, both strings are equal to "let", and the answer is 100+101+101+101 = 403.
If instead we turned both strings into "lee" or "eet", we would get answers of 433 or 417, which are higher.
Constraints:
1 <= s1.length, s2.length <= 1000
s1
and s2
consist of lowercase English letters.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We need to find the smallest sum of character values to delete from two strings so they become identical. The brute force way is to consider all possible deletions from both strings, comparing the results, and picking the option with the lowest sum of deleted character values.
Here's how the algorithm would work step-by-step:
def minimum_ascii_delete_sum_brute_force(string1, string2):
minimum_delete_sum = float('inf')
def calculate_delete_sum(deleted_characters):
delete_sum = 0
for character in deleted_characters:
delete_sum += ord(character)
return delete_sum
def find_minimum_delete_sum(index_string1, index_string2, current_string1, current_string2, deleted_characters):
nonlocal minimum_delete_sum
# If we've reached the end of both strings
if index_string1 == len(string1) and index_string2 == len(string2):
if current_string1 == current_string2:
delete_sum = calculate_delete_sum(deleted_characters)
minimum_delete_sum = min(minimum_delete_sum, delete_sum)
return
# If we've reached the end of the first string
if index_string1 == len(string1):
remaining_characters = string2[index_string2:]
find_minimum_delete_sum(index_string1, len(string2), current_string1, current_string2, deleted_characters + list(remaining_characters))
return
# If we've reached the end of the second string
if index_string2 == len(string2):
remaining_characters = string1[index_string1:]
find_minimum_delete_sum(len(string1), index_string2, current_string1, current_string2, deleted_characters + list(remaining_characters))
return
# Option 1: Delete a character from string1
find_minimum_delete_sum(index_string1 + 1, index_string2, current_string1, current_string2, deleted_characters + [string1[index_string1]])
# Option 2: Delete a character from string2
find_minimum_delete_sum(index_string1, index_string2 + 1, current_string1, current_string2, deleted_characters + [string2[index_string2]])
# Because it could result in the smallest sum
# Option 3: Keep both characters
find_minimum_delete_sum(index_string1 + 1, index_string2 + 1, current_string1 + string1[index_string1], current_string2 + string2[index_string2], deleted_characters)
find_minimum_delete_sum(0, 0, '', '', [])
return minimum_delete_sum
The best way to solve this problem is to use a strategy where we build up the solution gradually. We consider smaller parts of the problem and combine their solutions to solve the overall problem, avoiding redundant calculations. This prevents us from needing to check every single possible deletion.
Here's how the algorithm would work step-by-step:
def minimum_delete_sum(string1, string2):
string1_length = len(string1)
string2_length = len(string2)
# Initialize DP table
dp_table = [[0 for _ in range(string2_length + 1)] for _ in range(string1_length + 1)]
# Fill first row, cost of deleting all of string1
for string1_index in range(1, string1_length + 1):
dp_table[string1_index][0] = dp_table[string1_index - 1][0] + ord(string1[string1_index - 1])
# Fill first column, cost of deleting all of string2
for string2_index in range(1, string2_length + 1):
dp_table[0][string2_index] = dp_table[0][string2_index - 1] + ord(string2[string2_index - 1])
for string1_index in range(1, string1_length + 1):
for string2_index in range(1, string2_length + 1):
# If chars match, no deletion needed
if string1[string1_index - 1] == string2[string2_index - 1]:
dp_table[string1_index][string2_index] = dp_table[string1_index - 1][string2_index - 1]
else:
# Choose min cost of deleting from string1 or string2
dp_table[string1_index][string2_index] = min(
dp_table[string1_index - 1][string2_index] + ord(string1[string1_index - 1]),
dp_table[string1_index][string2_index - 1] + ord(string2[string2_index - 1])
)
# Final value is in the bottom right
return dp_table[string1_length][string2_length]
Case | How to Handle |
---|---|
Both strings are empty | Return 0, as no deletions are needed. |
One string is empty, the other is not | Return the sum of ASCII values of the non-empty string. |
Strings are identical | Return 0, no deletions are necessary. |
Strings have one character each and they are the same | Return 0 since no deletion is necessary. |
Strings have one character each and they are different | Return the sum of the ASCII values of the two characters. |
Strings have maximum allowed length (e.g. 1000 for typical constraints) | Ensure the dynamic programming table doesn't exceed memory limits and the algorithm's time complexity is efficient. |
Strings contain non-ASCII characters | The solution should correctly handle extended ASCII characters or throw an exception if it's designed for basic ASCII. |
Strings contain only a single repeated character each | The DP algorithm should handle this case efficiently, potentially requiring many similar computations. |