[Algorithm] Dynamic programming - 01 - Drawing 2-d matrix
Problem: Levenshtein Distance
Write a function that takes in two strings and returns the minimum number of edit operations that need to be performed on the first string to obtain the second string. There are three edit operations: insertion of a character, deletion of a character, and substitution of a character for another.
str1 = "abc"
str2 = "yabd"
Sample Output
2 // insert "y"; substitute "c" for "d"
Code:
查看代码
function minEditOps(str1, str2) {
const m = str1.length;
const n = str2.length;
// Initialize a 2D array with zeros
const dp = Array.from({ length: m + 1 }, () =>
Array.from({ length: n + 1 }, () => 0)
);
// Fill in the first row and column with incremental values
for (let i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (let j = 0; j <= n; j++) {
dp[0][j] = j;
}
// Fill in the rest of the matrix using dynamic programming
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (str1[i - 1] === str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] =
1 +
Math.min(
dp[i - 1][j - 1], // substitution
dp[i - 1][j], // deletion
dp[i][j - 1] // insertion
);
}
}
}
// The minimum number of edit operations is at the bottom right corner of the matrix
return dp[m][n];
}
Drawing a 2-d matrix
'' y a b d
'' 0 1 2 3 4 -> insertion
a 1 1 1 2 3
b 2 2 2 1 2
c 3 3 3 2 2
| \
deletion substitution
Looking at first row:
'' y a b d
'' 0 1 2 3 4 -> insertion
From left to right, we repeatly ask the question
from '' (column)
to '' (row)
, how many edits we need? 0
from '' (column)
to 'y'
, how many edits we need? insert 'y'
from '' (column)
to 'a'
, how many edits we need? based on current 'y', to 'ya', insert 'a'
from '' (column)
to 'b'
, how many edits we need? based on current 'ya', to 'yab', insert 'b'
from '' (column)
to 'd'
, how many edits we need? based on current 'yab', to 'yabd', insert 'd'
Every time we move one column, we use the result based on previou column, and operation we do is insertion.
Looking at first column
''
'' 0
a 1
b 2
c 3
|
deletion
from '' (column)
to '' (row)
, how many edits we need? 0
from 'a' (column)
to ''(row)
, how many edits we need? delete 'a'
from 'b' (column)
to ''(row)
, how many edits we need? already deleted 'a', nowdelete 'b'
from 'c' (column)
to ''(row)
, how many edits we need? already deleted 'ab', nowdelete 'c'
Every time, we move down one row, we do deletion
When column(a) equals row(a)
'' y a b d
'' 0 1 2 3 4 -> insertion
a 1 1 1
b 2
c 3
| \
deletion substitution
For example, we reach column(a) and row(a)
, because they are the same, so we do need to do anything, the same as column('') and row('y')
case. This operation is substitution
.
When column and row are different
'' y a b d
'' 0 1 2 3 4 -> insertion
a 1 1 1 2 3
b 2 2 2 1 2
c 3 3 3 2 ?
| \
deletion substitution
For example the ?
.
1 2
2 ?
We check the values and get min value then +1. so ? = 1 + 1 = 2