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

Best approachTime O(m * n)Space O(n)

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).

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * 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)
  1. What is the distance from an empty word to a word of length j?