Edit Distance (Levenshtein)
Problem
Two words are given on two lines. Print the minimum number of single-letter operations (insert a letter, delete a letter, or replace a letter) needed to change the first word into the second one.
Constraints
- 1 <= length <= 500
Examples
Input
horse ros
Output
3
Solutions
Look at the last letters. If equal, nothing is needed. If different, one operation is needed: replace (look at both prefixes shorter by 1), delete (shorten a) or insert (shorten b). We keep only two table rows, so the memory is O(n).
/*
* Problem : Find the edit distance.
* Input : Two words.
* Output : The minimum number of operations.
* Approach: Compare prefixes.
* Time : O(m * n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static int solve(String a, String b) {
// Step 1: previous[j] = the edit distance of the first i - 1 letters of a and the first j letters of b.
// Changing an empty word to the first j letters of b needs j insertions.
int[] previous = new int[b.length() + 1];
for (int j = 0; j <= b.length(); j++) {
previous[j] = j;
}
for (int i = 1; i <= a.length(); i++) {
// Step 2: current[0] = i, because we must delete i letters to get an empty word.
int[] current = new int[b.length() + 1];
current[0] = i;
for (int j = 1; j <= b.length(); j++) {
if (a.charAt(i - 1) == b.charAt(j - 1)) {
// Step 3: Equal letters cost nothing.
current[j] = previous[j - 1];
} else {
// Step 4: Otherwise take the cheapest of: replace, delete, insert. Each one costs 1 more.
current[j] = 1 + Math.min(previous[j - 1], Math.min(previous[j], current[j - 1]));
}
}
previous = current;
}
return previous[b.length()];
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String a = scanner.next();
String b = scanner.next();
System.out.println(solve(a, b));
}
}
Hints (1)
- What is the distance from an empty word to a word of length j?