The best way to think of the DP solution of this problem is to visualize it:
dp[i][j] - stands for edit distance between substring [0, i] of word1and substring [0, j] of word2
Thus dp[M][N] will be the result, where M is the length of (rows), and N is the length of word2 (columns)
For example:
| h o r s e | vs | r o s |
Since three types edit are allowed: Insert (I), Replace (R), Delete (R), showing each type of edit operation in the diagram for dp[2][2]
dp[2][2] is the edit distance of "ho" and "ro", and we can see,
1. "h" -> "r" known as dp[1][1] = 1,
2. or "ho" to "r" first, then "r" Insert "o"
3. or "h" to "ro" first, then "h" Insert "o"
then "ho" -> "ro", since the "o" is same for "ho" and "ro", then dp[2][2] will selecting the min among dp[1][2] + 1, dp[2][1] + 1, dp[1][1], which is 1
Note:dp[i][j] 2D array was initialized with word length + 1, since it's accounting for dp[0][0] would be empty string to empty string edit, also dp[M][N] will be the final result.
Thus when comparing, check word1.charAt(i - 1), word2.charAt(j - 1), since the index i, j means the i-th, j-th character instead of index in the string.
classSolution {publicintminDistance(String word1,String word2) {int n =word1.length();int m =word2.length();// if one of the strings is emptyif (n * m ==0)return n + m;// array to store the convertion historyint [][] d =newint[n +1][m +1];// init boundariesfor (int i =0; i < n +1; i++) { d[i][0] = i; }for (int j =0; j < m +1; j++) { d[0][j] = j; }// DP compute for (int i =1; i < n +1; i++) {for (int j =1; j < m +1; j++) {int left = d[i -1][j] +1;int down = d[i][j -1] +1;int left_down = d[i -1][j -1];if (word1.charAt(i -1) !=word2.charAt(j -1)) left_down +=1; d[i][j] =Math.min(left,Math.min(down, left_down)); } }return d[n][m]; }}