You are given two strings word1 and word2. Return the fewest operations that turn word1 into word2.
There are three operations, and each one counts as one:
- Insert a character anywhere in the word.
- Delete a character.
- Replace a character with another one.
Example 1:
Input: word1 = "horse", word2 = "ros" Output: 3 Explanation: horse -> rorse (replace 'h' with 'r') rorse -> rose (delete 'r') rose -> ros (delete 'e') Two operations are not enough: "ros" is two characters shorter, so both would have to be deletes, and deleting letters from "horse" never gives "ros", because its 'o' comes before its 'r'.
Example 2:
Input: word1 = "intention", word2 = "execution" Output: 5 Explanation: intention -> inention (delete 't') inention -> enention (replace 'i' with 'e') enention -> exention (replace 'n' with 'x') exention -> exection (replace 'n' with 'c') exection -> execution (insert 'u')
Example 3:
Input: word1 = "", word2 = "abc" Output: 3 Explanation: The empty word becomes "abc" by inserting its 3 characters. Each operation adds at most one character, so no fewer will do.
Constraints:
0 <= word1.length, word2.length <= 500word1andword2are made of lowercase English letters only,atoz. Either of them can be empty.
Note:
Your algorithm should run in O(m · n) time and space, where m is the length of word1 and n the length of word2.
Trying every sequence of operations is far too slow. Solve smaller versions of the problem instead: let
dp[i][j] be the fewest operations that turn the first i characters of word1 into the first j characters of word2. The table has (m + 1) × (n + 1) entries, and the answer is dp[m][n].Row 0 and column 0 stand for an empty prefix. Turning
i characters into nothing takes i deletes, so dp[i][0] = i; turning nothing into j characters takes j inserts, so dp[0][j] = j.
Fill the table row by row, so the entries above, to the left and diagonally up-left of
dp[i][j] are already known. Look at the last characters of the two prefixes, word1[i - 1] and word2[j - 1]:
- When they are equal, they need no operation:
dp[i][j] = dp[i - 1][j - 1]. Spending an operation on either of them is never better. - When they differ, one operation fixes the end of the prefix, and
dp[i][j]is 1 plus the smallest of three neighbours:dp[i - 1][j - 1]: replaceword1[i - 1]withword2[j - 1]; both prefixes are then one character shorter.dp[i - 1][j]: deleteword1[i - 1]; only the prefix ofword1is shorter.dp[i][j - 1]: insertword2[j - 1]at the end; it matches the last character ofword2's prefix, which is then one shorter.
The table has
(m + 1) × (n + 1) entries, and each one takes a constant amount of work: O(m · n) time and O(m · n) space.Each row reads only itself and the row above it, so two rows of
n + 1 numbers are enough, which brings the space down to O(n). The lesson keeps the whole table, which is easier to follow.
Free plan: 30 tutor messages. Premium is unlimited.
Saved
Ctrl + Enter to check
