Проблема кодирования: Учитывая строку S и символ C, найдите расстояние для всех символов в строке к символу C в строке с. Вы можете предположить, что символ C появится хотя бы один раз в строке. Эта проблема была недавно спросила Uber.
Пример:
Например, дано shortest_dist ('helloworld', 'l') , вы должны вернуть [2, 1, 0, 0, 1, 2, 2, 1, 0, 1] .
Решение проблемы:
1) Техника: раздвижные окна (в этом случае два окна справа и влево)
Запуск окна и конечные указатели:
Начальные и конечные указатели окна позволяют нам пройти через цепь, увеличивая или уменьшая размер окна, в начале указатель «конец» является единственным, который увеличивается, начальный указатель сохраняет положение до этого. Чар появляется на сцене. С появлением CHAR, Pivot обновляется, размер окна и расстояния между поворотом и элементами, которые сформировали окно до этого момента, обновляются.
Измените размер окна:
Мы можем изменить размер окна, когда мы находим вхождение персонажа в. Индекс «конец» окна проходит через всю цепочку, и начало поддерживает положение, пока мы не найдем pivot = (Вступления в Чар).
Вращаться:
Переменные поворота позволяют нам иметь контрольную точку для последнего появления в цепочке, с этим поворотом мы рассчитаем расстояние между конечным указателем и последним появлением CHAR.
Большой O (n):
Короче говоря, могу сказать, что это решение имеет O (N * M), где «n» – это длина «ST» и «M» – это вхождения «CHAR». Таким образом, внутренний цикл просто для обновления указателя «старта» и «pivot», чем больше случаев персонажа, тем больше раз эта цикл будет работать. Наконец, O (n) – лучший шаблон для описания поведения этих алгоритмов. Мы подчеркиваем факт использования двух окон, чтобы пройти через цепочку, это уменьшается в определенной степени размер циклов обновлений.
Код:
function shortestDist(st, char) {
let len = st.length - 1
let [
winLeftStart,
winLeftEnd,
winRightStart,
winRightEnd
] = [0, 0, len, len];
let [pivotLeft, pivotRight] = [null, null];
let dist = [];
while (winLeftEnd <= len) {
/** Window Left*/
if (st[winLeftEnd] === char) {
pivotLeft = winLeftEnd;
while (winLeftStart <= pivotLeft) {
dist[winLeftStart] = pivotLeft - winLeftStart;
++winLeftStart;
}
} if (!!pivotLeft) {
if (dist[winLeftEnd]) {
//End when have first match in dist
dist[winLeftEnd] =
dist[winLeftEnd] < winLeftEnd - pivotLeft ?
dist[winLeftEnd] :
winLeftEnd - pivotLeft;
return dist;
}
dist[winLeftEnd] = winLeftEnd - pivotLeft;
}
/** Window right*/
if (st[winRightEnd] === char) {
pivotRight = winRightEnd;
while (winRightStart >= pivotRight) {
dist[winRightStart] = winRightStart - pivotRight;
--winRightStart;
}
} else if (!!pivotRight) {
dist[winRightEnd] = pivotRight - winRightEnd;
}
/** Grow Windows*/
--winRightEnd;
++winLeftEnd;
}
return [];
}
Простой тест:
console.log(shortestDist('helloworld', 'l'))
// h e l l o w o r l d
// resp. [2, 1, 0, 0, 1, 2, 2, 1, 0, 1]
// 0 1 2 3 4 5 6 7 8 9
Вы можете проверить Код по @ difo23.
Оригинал: “https://dev.to/difo23/technique-sliding-windows-algorithms-55oe”