# Edit Distance | DP using Memoization

Given two strings str1 and str2 and below operations that can be performed on str1. Find the minimum number of edits (operations) required to convert ‘str1’ into ‘str2’.

- Insert
- Remove
- Replace

All of the above operations are of equal cost.

**Examples:**

Input:str1 = “geek”, str2 = “gesek”

Output:1

We can convert str1 into str2 by inserting a ‘s’.

Input:str1 = “cat”, str2 = “cut”

Output:1

We can convert str1 into str2 by replacing ‘a’ with ‘u’.

Input:str1 = “sunday”, str2 = “saturday”

Output:3

Last three and first characters are same. We basically

need to convert “un” to “atur”. This can be done using

below three operations.

Replace ‘n’ with ‘r’, insert t, insert a

<div

**What are the subproblems in this case?** The idea is to process all characters one by one staring from either from left or right sides of both strings. Let us traverse from right corner, there are two possibilities for every pair of character being traversed. The following are the conditions:

- If last characters of two strings are same, nothing much to do. Ignore last characters and get count for remaining strings. So we recur for lengths m-1 and n-1.
- Else (If last characters are not same), we consider all operations on ‘str1’, consider all three operations on last character of first string, recursively compute minimum cost for all three operations and take minimum of three values.
**Insert:**Recur for m and n-1**Remove:**Recur for m-1 and n**Replace:**Recur for m-1 and n-1

Below is the implementation of the above approach:

## C++

`// A Naive recursive C++ program to find minimum number ` `// operations to convert str1 to str2 ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Utility function to find minimum of three numbers ` `int` `min(` `int` `x, ` `int` `y, ` `int` `z) ` `{ ` ` ` `return` `min(min(x, y), z); ` `} ` ` ` `int` `editDist(string str1, string str2, ` `int` `m, ` `int` `n) ` `{ ` ` ` `// If first string is empty, the only option is to ` ` ` `// insert all characters of second string into first ` ` ` `if` `(m == 0) ` ` ` `return` `n; ` ` ` ` ` `// If second string is empty, the only option is to ` ` ` `// remove all characters of first string ` ` ` `if` `(n == 0) ` ` ` `return` `m; ` ` ` ` ` `// If last characters of two strings are same, nothing ` ` ` `// much to do. Ignore last characters and get count for ` ` ` `// remaining strings. ` ` ` `if` `(str1[m - 1] == str2[n - 1]) ` ` ` `return` `editDist(str1, str2, m - 1, n - 1); ` ` ` ` ` `// If last characters are not same, consider all three ` ` ` `// operations on last character of first string, recursively ` ` ` `// compute minimum cost for all three operations and take ` ` ` `// minimum of three values. ` ` ` `return` `1 + min(editDist(str1, str2, m, n - 1), ` `// Insert ` ` ` `editDist(str1, str2, m - 1, n), ` `// Remove ` ` ` `editDist(str1, str2, m - 1, n - 1) ` `// Replace ` ` ` `); ` `} ` ` ` `// Driver program ` `int` `main() ` `{ ` ` ` `// your code goes here ` ` ` `string str1 = ` `"sunday"` `; ` ` ` `string str2 = ` `"saturday"` `; ` ` ` ` ` `cout << editDist(str1, str2, str1.length(), str2.length()); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// A Naive recursive Java program to find minimum number ` `// operations to convert str1 to str2 ` `class` `EDIST { ` ` ` `static` `int` `min(` `int` `x, ` `int` `y, ` `int` `z) ` ` ` `{ ` ` ` `if` `(x <= y && x <= z) ` ` ` `return` `x; ` ` ` `if` `(y <= x && y <= z) ` ` ` `return` `y; ` ` ` `else` ` ` `return` `z; ` ` ` `} ` ` ` ` ` `static` `int` `editDist(String str1, String str2, ` `int` `m, ` `int` `n) ` ` ` `{ ` ` ` `// If first string is empty, the only option is to ` ` ` `// insert all characters of second string into first ` ` ` `if` `(m == ` `0` `) ` ` ` `return` `n; ` ` ` ` ` `// If second string is empty, the only option is to ` ` ` `// remove all characters of first string ` ` ` `if` `(n == ` `0` `) ` ` ` `return` `m; ` ` ` ` ` `// If last characters of two strings are same, nothing ` ` ` `// much to do. Ignore last characters and get count for ` ` ` `// remaining strings. ` ` ` `if` `(str1.charAt(m - ` `1` `) == str2.charAt(n - ` `1` `)) ` ` ` `return` `editDist(str1, str2, m - ` `1` `, n - ` `1` `); ` ` ` ` ` `// If last characters are not same, consider all three ` ` ` `// operations on last character of first string, recursively ` ` ` `// compute minimum cost for all three operations and take ` ` ` `// minimum of three values. ` ` ` `return` `1` `+ min(editDist(str1, str2, m, n - ` `1` `), ` `// Insert ` ` ` `editDist(str1, str2, m - ` `1` `, n), ` `// Remove ` ` ` `editDist(str1, str2, m - ` `1` `, n - ` `1` `) ` `// Replace ` ` ` `); ` ` ` `} ` ` ` ` ` `public` `static` `void` `main(String args[]) ` ` ` `{ ` ` ` `String str1 = ` `"sunday"` `; ` ` ` `String str2 = ` `"saturday"` `; ` ` ` ` ` `System.out.println(editDist(str1, str2, str1.length(), str2.length())); ` ` ` `} ` `} ` |

*chevron_right*

*filter_none*

## Python

`# A Naive recursive Python program to fin minimum number ` `# operations to convert str1 to str2 ` `def` `editDistance(str1, str2, m, n): ` ` ` ` ` `# If first string is empty, the only option is to ` ` ` `# insert all characters of second string into first ` ` ` `if` `m ` `=` `=` `0` `: ` ` ` `return` `n ` ` ` ` ` `# If second string is empty, the only option is to ` ` ` `# remove all characters of first string ` ` ` `if` `n ` `=` `=` `0` `: ` ` ` `return` `m ` ` ` ` ` `# If last characters of two strings are same, nothing ` ` ` `# much to do. Ignore last characters and get count for ` ` ` `# remaining strings. ` ` ` `if` `str1[m` `-` `1` `]` `=` `=` `str2[n` `-` `1` `]: ` ` ` `return` `editDistance(str1, str2, m` `-` `1` `, n` `-` `1` `) ` ` ` ` ` `# If last characters are not same, consider all three ` ` ` `# operations on last character of first string, recursively ` ` ` `# compute minimum cost for all three operations and take ` ` ` `# minimum of three values. ` ` ` `return` `1` `+` `min` `(editDistance(str1, str2, m, n` `-` `1` `), ` `# Insert ` ` ` `editDistance(str1, str2, m` `-` `1` `, n), ` `# Remove ` ` ` `editDistance(str1, str2, m` `-` `1` `, n` `-` `1` `) ` `# Replace ` ` ` `) ` ` ` `# Driver program to test the above function ` `str1 ` `=` `"sunday"` `str2 ` `=` `"saturday"` `print` `editDistance(str1, str2, ` `len` `(str1), ` `len` `(str2)) ` |

*chevron_right*

*filter_none*

## C#

`// A Naive recursive C# program to ` `// find minimum numberoperations ` `// to convert str1 to str2 ` `using` `System; ` ` ` `class` `GFG { ` ` ` `static` `int` `min(` `int` `x, ` `int` `y, ` `int` `z) ` ` ` `{ ` ` ` `if` `(x <= y && x <= z) ` ` ` `return` `x; ` ` ` `if` `(y <= x && y <= z) ` ` ` `return` `y; ` ` ` `else` ` ` `return` `z; ` ` ` `} ` ` ` ` ` `static` `int` `editDist(String str1, String str2, ` `int` `m, ` `int` `n) ` ` ` `{ ` ` ` `// If first string is empty, the only option is to ` ` ` `// insert all characters of second string into first ` ` ` `if` `(m == 0) ` ` ` `return` `n; ` ` ` ` ` `// If second string is empty, the only option is to ` ` ` `// remove all characters of first string ` ` ` `if` `(n == 0) ` ` ` `return` `m; ` ` ` ` ` `// If last characters of two strings are same, nothing ` ` ` `// much to do. Ignore last characters and get count for ` ` ` `// remaining strings. ` ` ` `if` `(str1[m - 1] == str2[n - 1]) ` ` ` `return` `editDist(str1, str2, m - 1, n - 1); ` ` ` ` ` `// If last characters are not same, consider all three ` ` ` `// operations on last character of first string, recursively ` ` ` `// compute minimum cost for all three operations and take ` ` ` `// minimum of three values. ` ` ` `return` `1 + min(editDist(str1, str2, m, n - 1), ` `// Insert ` ` ` `editDist(str1, str2, m - 1, n), ` `// Remove ` ` ` `editDist(str1, str2, m - 1, n - 1) ` `// Replace ` ` ` `); ` ` ` `} ` ` ` ` ` `// Driver code ` ` ` `public` `static` `void` `Main() ` ` ` `{ ` ` ` `String str1 = ` `"sunday"` `; ` ` ` `String str2 = ` `"saturday"` `; ` ` ` `Console.WriteLine(editDist(str1, str2, str1.Length, ` ` ` `str2.Length)); ` ` ` `} ` `} ` |

*chevron_right*

*filter_none*

**Output:**

3

The time complexity of above solution is O(3^n) which is exponential. The worst case happens when none of characters of two strings match. Below is a recursive call diagram for worst case.

We can see that many subproblems are solved, again and again, for example, eD(2, 2) is called three times. Since same suproblems are called again, this problem has Overlapping Subprolems property. So Edit Distance problem has both properties (see this and this) of a dynamic programming problem. Like other typical Dynamic Programming(DP) problems, recomputations of same subproblems can be avoided by constructing a temporary array that stores results of subproblems. The bottom-up approach can be found here.

The problem can also be solved using top-down Dynamic Programming and using memoization. In the recursive code, memoization can be used to avoid overlapping problems. There are several repetitive calls which can be computed in O(1) if the value is stored when called for the first time. On observing the recursive code, it is seen that a maximum of two parameters is changing their value on every recursive call. There will be cases when the same recursive call has been called previously. Since two parameters are not constant, a 2-D array can be used to avoid repetitive calls. Hence the return value is stored in some 2-D array. Below are the steps:

- Initialize a 2-D DP array of size m *n with -1 at all the index.
- On every recursive call, store the return value at dp[m][n] so that if
*func(m, n)*is called again, it can be answered in O(1) without using recursion. - Check if the recursive call has been visited previously or not by checking the value at dp[m][n].

Below is the implementation of the above approach:

`// A memoization program to find minimum number ` `// operations to convert str1 to str2 ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// Maximum 2-D array coloumn size ` `const` `int` `maximum = 1000; ` ` ` `// Utility function to find minimum of three numbers ` `int` `min(` `int` `x, ` `int` `y, ` `int` `z) ` `{ ` ` ` `return` `min(min(x, y), z); ` `} ` ` ` `int` `editDist(string str1, string str2, ` `int` `m, ` `int` `n, ` `int` `dp[][maximum]) ` `{ ` ` ` `// If first string is empty, the only option is to ` ` ` `// insert all characters of second string into first ` ` ` `if` `(m == 0) ` ` ` `return` `n; ` ` ` ` ` `// If second string is empty, the only option is to ` ` ` `// remove all characters of first string ` ` ` `if` `(n == 0) ` ` ` `return` `m; ` ` ` ` ` `// if the recursive call has been ` ` ` `// called previously, then return ` ` ` `// the stored value that was calculated ` ` ` `// previously ` ` ` `if` `(dp[m - 1][n - 1] != -1) ` ` ` `return` `dp[m - 1][n - 1]; ` ` ` ` ` `// If last characters of two strings are same, nothing ` ` ` `// much to do. Ignore last characters and get count for ` ` ` `// remaining strings. ` ` ` ` ` `// Store the returned value at dp[m-1][n-1] ` ` ` `// considering 1-based indexing ` ` ` `if` `(str1[m - 1] == str2[n - 1]) ` ` ` `return` `dp[m - 1][n - 1] = editDist(str1, str2, m - 1, n - 1, dp); ` ` ` ` ` `// If last characters are not same, consider all three ` ` ` `// operations on last character of first string, recursively ` ` ` `// compute minimum cost for all three operations and take ` ` ` `// minimum of three values. ` ` ` ` ` `// Store the returned value at dp[m-1][n-1] ` ` ` `// considering 1-based indexing ` ` ` `return` `dp[m - 1][n - 1] = 1 + min(editDist(str1, str2, m, n - 1, dp), ` `// Insert ` ` ` `editDist(str1, str2, m - 1, n, dp), ` `// Remove ` ` ` `editDist(str1, str2, m - 1, n - 1, dp) ` `// Replace ` ` ` `); ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` ` ` `string str1 = ` `"sunday"` `; ` ` ` `string str2 = ` `"saturday"` `; ` ` ` `int` `m = str1.length(); ` ` ` `int` `n = str2.length(); ` ` ` ` ` `// Declare a dp array which stores ` ` ` `// the answer to recursive calls ` ` ` `int` `dp[m][maximum]; ` ` ` ` ` `// initially all index with -1 ` ` ` `memset` `(dp, -1, ` `sizeof` `dp); ` ` ` ` ` `// Function call ` ` ` `// memoization nad top-down approach ` ` ` `cout << editDist(str1, str2, m, n, dp); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output: **

3

**Time Complexity**: O(M * N)

**Auxiliary Space**: O(M * N)

## Recommended Posts:

- Edit Distance | DP-5
- Check if edit distance between two strings is one
- Edit distance and LCS (Longest Common Subsequence)
- Print all possible ways to convert one string into another string | Edit-Distance
- Memoization (1D, 2D and 3D)
- Tabulation vs Memoization
- Water Jug Problem using Memoization
- Memoization using decorators in Python
- Longest Common Subsequence | DP using Memoization
- Check whether Strings are k distance apart or not
- Hamming Distance between two strings
- Minimum distance to the end of a grid from source
- Rearrange a string so that all same characters become d distance away
- Minimum Distance Between Words of a String
- Maximum sum possible for a sub-sequence such that no two elements appear at a distance < K in the array

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.