Я думаю, что вы можете решить эту проблему, используя довольно элегантный алгоритм динамического программирования, который выполняется за время O (mn) и пространство O (mn), где m и n - количество символов в каждой строке.Идея основана на следующем повторении.Пусть две строки: A = a 0 a 1 a 2 ... a n-1 и B = b 0 b 1 b 2 ... b m-1 и посмотрите на их первые символы a 0 и b 0 .Тогда есть три способа найти самую длинную общую подпоследовательность:
- Если первые символы равны, одним из вариантов будет найти самые длинные общие подпоследовательности остальных двух строк, тогдачтобы добавить первый символ к совпадению.
- В качестве альтернативы, вы можете решить не совпадать с первыми двумя символами.В этом случае одним из вариантов будет посмотреть, какую самую длинную общую подпоследовательность вы можете создать, игнорируя первый символ первой строки.3 Наконец, вы также можете игнорировать первый символ второй строки.
Это дает нам очень хорошее повторение:
LCS(A[0 .. n], B[0 .. m]) = longest of {
A[0] + LCS(A[1 .. n], B[1 .. m]) (if A[0] == B[0]),
LCS(A[1 .. n], B[0 .. m]),
LCS(A[0 .. n], B[1 .. m])
}
В качестве наших базовых случаев самая длинная общая подстрокалюбой строки, а пустая строка - пустая строка:
LCS (A[n .. n], B[i, m]) = ""
LCS (A[i .. n], B[m, m]) = ""
Это определение самой длинной общей подстроки позволяет вычислить значение LCS (A [i .. n], B [j ..m]) с учетом трех значений LCS (A [i + 1 .. n], B [j + 1 ... m]), LCS (A [i .. n], B [j + 1 ... m])и LCS (A [i + 1 .. n], B [j ... m]).Следовательно, если вы вычисляете эти значения в правильном порядке, вы можете просто заполнить таблицу результатами за один проход и построить результат оттуда.Используя некоторые стандартные трюки DP, это можно сделать для запуска в O (mn).