Редактировать : очевидно, есть алгоритм O (n) (см. Ответ алгоритмиста). Очевидно, что это побьет базовый уровень [наивный], описанный ниже!
Жаль, что мне пора ... Я немного подозреваю, что мы можем получить O (n). Завтра я проверю, чтобы увидеть победителя ;-) Удачи!
Предварительный алгоритм :
Общая идея состоит в том, чтобы последовательно попытаться использовать символ из str2, найденный в str1, в качестве начала поиска (в обоих направлениях) всех других букв str2. Сохраняя значение «длина наилучшего совпадения», мы можем прервать поиск, когда он превысит это значение. Другие эвристики, вероятно, могут быть использованы для дальнейшего прерывания неоптимальных (пока) решений. Выбор порядка начальных букв в str1 имеет большое значение; предлагается начинать с буквы (букв) str1, которые имеют наименьшее число, и пытаться использовать другие буквы увеличивающегося числа в последующих попытках.
[loose pseudo-code]
- get count for each letter/character in str1 (number of As, Bs etc.)
- get count for each letter in str2
- minLen = length(str1) + 1 (the +1 indicates you're not sure all chars of
str2 are in str1)
- Starting with the letter from string2 which is found the least in string1,
look for other letters of Str2, in either direction of str1, until you've
found them all (or not, at which case response = impossible => done!).
set x = length(corresponding substring of str1).
- if (x < minLen),
set minlen = x,
also memorize the start/len of the str1 substring.
- continue trying with other letters of str1 (going the up the frequency
list in str1), but abort search as soon as length(substring of strl)
reaches or exceed minLen.
We can find a few other heuristics that would allow aborting a
particular search, based on [pre-calculated ?] distance between a given
letter in str1 and some (all?) of the letters in str2.
- the overall search terminates when minLen = length(str2) or when
we've used all letters of str1 (which match one letter of str2)
as a starting point for the search