Полевой справочник
Два указателя (в одну сторону)
O(n)Медленный указатель записи и быстрый указатель чтения оба движутся слева направо; быстрый сканирует вперёд, а медленный продвигается только когда значение стоит сохранить.
Сигналы
удалить дубликаты на месте, сохранив порядокпереместить/разбить элементы с сохранением порядкасжать массив, используя O(1) дополнительной памятисдвинуть нули или заданное значение в конец
Шаблон
function compact(arr) {
let slow = 0;
for (let fast = 0; fast < arr.length; fast++) {
if (shouldKeep(arr[fast], arr[slow])) {
arr[slow] = arr[fast];
slow++;
}
}
return slow; // new length
}Похоже, но не то
- Преобразование массива на месте: Работа на месте это более широкая цель (переписать один буфер, O(1) памяти); пара медленный/быстрый указатель это конкретный механизм для неё. Некоторым задачам на месте, например развороту фиксированного блока, пара указателей вообще не нужна.
- Два указателя (с концов): Указатели с концов стартуют по краям отсортированных данных и сходятся навстречу друг другу. Указатели в одну сторону оба стартуют с индекса 0 и только движутся вперёд: один читает, другой пишет.
n до 1e5..1e6 -> O(n): быстрый указатель посещает каждый элемент один раз, медленный никогда его не обгоняет, поэтому хватает одного линейного прохода.
Изучить этот паттерн