Разумеется, будем считать, что слова не должны быть осмысленными (иначе это другая задача, где этот алгоритм, с одной стороны, тяжеловат, с другой — совсем не нужен). Если между словами «коза» и «волк» расстояние 3, то промежуточные слова — «коза → воза → вола → волк». Или, если не против, «коза → козк →колк → волк».
Итак, перед нами типичный алгоритм динамического программирования. В алгоритме динамического программирования есть два этапа: обратный ход и прямой. Этот алгоритм страдает двумя недостатками, мешающими взять и написать прямой ход.
1. Матрица сжата. Вместо матрицы (M+1)×(N+1) мы имеем два массива длины N+1, хранящие одну строчку и потихоньку перезаписываемые.
2. Нет второй матрицы, которая указывает направление, куда идти. В нашем случае направления — это три действия над строкой: замена, вставка и удаление.
ну и 3) В сокращённом варианте хватит двух массивов, обмениваемых местами. К делу отношения не имеет, просто вопросы умелого программирования. Кажется, перед нами Java и утечек памяти тут нет — тем лучше.
С задачами 1 и 2 надо сделать три вещи.
1. Массивы D1 и D2 превратить в единую матрицу (M+1)×(N+1).
2. Добавить второй такой же. Элементы его — enum: удалить/вставить/заменить.
3. Написать прямой ход. Мы находимся в точке (M, N); смотрим, куда идти. Заменить — идём туда-то, вставить — идём туда-то, удалить — идём туда-то. Ну и, разумеется, выполняем нашу операцию на строках и выводим, что получилось. Продолжаем путь, пока не попадём в (0, 0).