Aller au contenu
  1. Algorithmes & Structures de données/
#94 DP Difficile 2 min de lecture

Edit Distance

Nombre MINIMAL d’opérations (insérer, supprimer, remplacer un caractère) pour transformer word1 en word2. Ex : “horse” → “ros” = 3. La distance de Levenshtein, au cœur des correcteurs orthographiques.

🐻 Vocabulaire pas clair ? Consultez le glossaire algo.

C’est quoi le problème, en clair ? #

On vous donne deux mots et vous devez transformer le premier en le second en changeant le moins de lettres possible : vous avez le droit d’ajouter, de supprimer ou de remplacer une lettre à la fois, et chaque geste compte comme une opération. C’est exactement ce que fait un correcteur orthographique quand il vous propose un mot proche de celui que vous venez de taper par erreur : il calcule combien de petites retouches séparent votre faute du mot correct. Imaginez que vous réécrivez un mot sur une ardoise, lettre par lettre, et que chaque effaçage ou ajout compte comme un point : le but est de trouver le chemin le plus économique d’un mot à l’autre.

L’idée clé #

DP 2D sur les préfixes, cousine directe de LCS ( Longest Common Subsequence) : dp[i][j] = distance entre les i premiers caractères de word1 et les j premiers de word2. Derniers caractères égaux → dp[i-1][j-1] (gratuit). Sinon → 1 + min(remplacer dp[i-1][j-1], supprimer dp[i-1][j], insérer dp[i][j-1]).

Pourquoi cette solution ? #

L’initialisation raconte l’histoire : dp[i][0] = i (tout supprimer), dp[0][j] = j (tout insérer). Savoir NOMMER l’opération derrière chacune des trois cases voisines est ce que l’interviewer vérifie — c’est la preuve qu’on comprend la table au lieu de la réciter. Compression possible à deux lignes O(min(N,M)).

Solution Java #

class Solution {
    public int minDistance(String word1, String word2) {
        int n = word1.length(), m = word2.length();
        int[][] dp = new int[n + 1][m + 1];

        // Cas de base : transformer un prefixe en chaine vide (et inversement)
        for (int i = 0; i <= n; i++) dp[i][0] = i; // i suppressions
        for (int j = 0; j <= m; j++) dp[0][j] = j; // j insertions

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1]; // caracteres identiques : gratuit
                } else {
                    dp[i][j] = 1 + Math.min(
                        dp[i - 1][j - 1],                    // remplacer
                        Math.min(dp[i - 1][j],               // supprimer dans word1
                                 dp[i][j - 1]));             // inserer dans word1
                }
            }
        }
        return dp[n][m];
    }
}

Complexité #

Temps O(N×M) : remplissage de la table. Espace O(N×M), réductible à O(min(N,M)) avec deux lignes.