Grokking LinkedIn Coding Interview
Ask Author
Back to course home

0% completed

Vote For New Content
Solution: Edit Distance
Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Problem Statement

Given two strings word1 and word2, return the least number of edits needed to transform word1 to word2.

You can perform any one edit from below three in a single operation on Word:

  • Insert a character
  • Delete a character
  • Replace a character

Examples

  • Example 1:

    • Input: word1 = "cat", word2 = "cut"
    • Expected Output: 1
    • Justification: Only one operation is needed, replacing 'a' with 'u' in "cat" to make it "cut".
  • Example 2:

    • Input: word1 = "sun", word2 = "satur"
    • Expected Output: 3
    • Justification: Three operations needed: 1) Insert 'a' after 's', 2) Insert 't' after 'a', and 3) Replace 'n' with 'r'.
  • Example 3:

    • Input: word1 = "book", word2 = "back"
    • Expected Output: 2
    • Justification: Two operations are required: 1) Replace 'o' with 'a', and 2) Replace the second 'o' with 'c'. This changes "book" to "back".

Solution

To solve this problem, we'll use dynamic programming due to its efficiency in solving problems that involve making a sequence of decisions. The core idea is to break down the problem into simpler, smaller subproblems and store their solutions to avoid redundant calculations. This approach works well here because the edit distance between two substrings can be built up from the edit distances of their prefixes, allowing for an efficient bottom-up calculation.

The effectiveness of this approach lies in its ability to consider all possible edit operations in a systematic way. By examining the relationships between the edits required for different substring lengths, we can construct a solution that covers all possible paths from the start string to the target string, ensuring that the minimum edit distance is found. This method not only guarantees accuracy but also significantly reduces computational overhead compared to naive recursive approaches.

Step-by-Step Algorithm

  1. Initialization: Start by creating a 2D array, dp, with dimensions [word1.length() + 1][word2.length() + 1]. This array will hold the minimum number of operations required to convert substrings of word1 to substrings of word2. The +1 accounts for the zero-length substrings of both words.

  2. Base Cases: Fill in the base cases in the dp array.

    • Fill the first row, dp[0][j], with j, representing the minimum number of insert operations needed to convert an empty string into the first j characters of word2.
    • Fill the first column, dp[i][0], with i, representing the minimum number of delete operations needed to convert the first i characters of word1 into an empty string.
  3. Filling the DP Table: Iterate through each cell of the dp array starting from dp[1][1] to dp[word1.length()][word2.length()]. For each cell dp[i][j], compute the minimum of the following operations:

    • Deletion: Remove a character from word1. This operation is represented by dp[i-1][j] + 1.
    • Insertion: Add a character to word1 to match a character in word2. This operation is represented by dp[i][j-1] + 1.
    • Replacement: If the current characters in word1 and word2 don't match, replace the character in word1 with the matching character from word2. This operation is represented by dp[i-1][j-1] + 1. If the characters already match, simply carry over the value from dp[i-1][j-1].
  4. Result: After filling the dp table, the value in dp[word1.length()][word2.length()] will be the minimum number of operations required to convert word1 into word2.

Algorithm Walkthrough

Let's walkthrough the Input: word1 = "sun", word2 = "saturday"

Initial DP Array

We initialize the DP array with dimensions [4][6] (since "sun" has 3 characters and "satur" has 5 characters, plus 1 for the base case of the empty string).

dp = [
  [x, x, x, x, x, x],
  [x, x, x, x, x, x],
  [x, x, x, x, x, x],
  [x, x, x, x, x, x]
]

Fill First Row and Column

  • The first row is filled with 0 to 5, representing the operation count needed to convert an empty string to each prefix of "satur".
  • The first column is filled with 0 to 3, representing the operation count needed to convert each prefix of "sun" to an empty string.

After filling the first row and column:

dp = [
  [0, 1, 2, 3, 4, 5],
  [1, x, x, x, x, x],
  [2, x, x, x, x, x],
  [3, x, x, x, x, x]
]

i = 0 (Comparing "s" with each character of "satur")

  1. "s" with "s": They match, so we carry over the value from dp[0][0], making dp[1][1] = 0.
  2. "s" with "a": They don't match, so we consider the minimum of the operations above, left, and diagonal-left plus one, making dp[1][2] = 1.
  3. "s" with "t": They don't match, continuing the logic, making dp[1][3] = 2.
  4. "s" with "u": They don't match, making dp[1][4] = 3.
  5. "s" with "r": They don't match, making dp[1][5] = 4.

After comparisons:

dp = [
  [0, 1, 2, 3, 4, 5],
  [1, 0, 1, 2, 3, 4],
  [2, x, x, x, x, x],
  [3, x, x, x, x, x]
]

i = 1 (Comparing "u" with each character of "satur")

  1. "u" with "s": Doesn't match, so we take the minimum of operations above, left, and diagonal-left plus one, making dp[2][1] = 1.
  2. "u" with "a": Doesn't match, continue with the logic, making dp[2][2] = 1.
  3. "u" with "t": Doesn't match, making dp[2][3] = 2.
  4. "u" with "u": They match, so we carry over the value from dp[1][3], making dp[2][4] = 2.
  5. "u" with "r": Doesn't match, making dp[2][5] = 3.

After comparisons:

dp = [
  [0, 1, 2, 3, 4, 5],
  [1, 0, 1, 2, 3, 4],
  [2, 1, 1, 2, 2, 3],
  [3, x, x, x, x, x]
]

i = 2 (Comparing "n" with each character of "satur")

  1. "n" with "s": Doesn't match, so we take the minimum of operations above, left, and diagonal-left plus one, making dp[3][1] = 2.
  2. "n" with "a": Doesn't match, continue with the logic, making dp[3][2] = 2.
  3. "n" with "t": Doesn't match, making dp[3][3] = 2.
  4. "n" with "u": Doesn't match, making dp[3][4] = 3.
  5. "n" with "r": Doesn't match, making dp[3][5] = 3.

After comparisons:



dp = [
  [0, 1, 2, 3, 4, 5],
  [1, 0, 1, 2, 3, 4],
  [2, 1, 1, 2, 2, 3],
  [3, 2, 2, 2, 3, 3]
]

Result

The minimum number of operations required to transform "sun" into "satur" is found in dp[3][5], which is 3.

Code

Python3
Python3

. . . .

Complexity Analysis

  • Time Complexity: The algorithm iterates through each character of both strings once to fill the DP table, resulting in a time complexity of O(m*n), where m and n are the lengths of word1 and word2, respectively.
  • Space Complexity: The space complexity is also O(m*n) due to the DP table that stores the edit distances between all prefixes of the two strings.

.....

.....

.....

Like the course? Get enrolled and start learning!

Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible