(Перекрестная публикация моего ответа от Quora здесь).
ИМО, вопрос не был сформулирован очень четко, но я думаю, что он задает следующий вопрос: нам дан набор строк S [1], S [2],…, S [N] и набор запросов, каждый из которых принимает форму (i1, j1, i2, j2, L).Ответ на такой запрос - «да», если строки длины L, начинающиеся в позиции j1 в S [i1] и в позиции j2 в S [i2], отличаются изменением не более чем на один символ, в противном случае - «нет».Сумма L-значений по всем таким запросам может быть намного больше, чем общая длина строк.
В этом случае мы можем разработать эффективный алгоритм, используя следующее наблюдение: если S и T - строкидлины L, то выражение «S и T различаются изменением не более одного символа» эквивалентно «LCP (S, T) + LCP (R (S), R (T))> = L-1»где R обозначает обращение строки, а LCP - длину самого длинного общего префикса двух строк.
Таким образом, для эффективного ответа на запросы нам нужно только предварительно обработать строки S [1],…, S [N] и R (S [1]),…, R (S [N]), поэтому запросы с самым длинным общим префиксом выполняются быстро.Это можно сделать путем объединения S [1],…, S [N], чтобы получить одну строку S, и построения массива суффиксов и массива самых длинных общих префиксов из S,затем делая то же самое для обратного S. Определение LCP двух подстрок исходных строк тогда эквивалентно определению LCP двух подстрок S (*), что эквивалентно запросу минимального диапазона в массиве LCP,на который можно эффективно ответить путем предварительной обработки.Аналогичное утверждение справедливо для обращений исходных строк и обращения к S.
(*) Технически, LCP в объединенной строке S может выходить за границы исходных строк.Однако это произойдет только в том случае, если подстроки запроса фактически идентичны, поэтому это будет означать, что мы ответим «да» в тех случаях, когда ответ «да» в любом случае.