Техника двух указателей
Два указателя — это чрезвычайно распространенная техника, используемая для решения задач с массивами и строками. Она включает использование двух целочисленных переменных, которые перемещаются по итерируемому объекту. В этой статье мы сосредоточимся на массивах и строках. Это означает, что у нас будут два целых числа, обычно называемые чем-то вроде i и j, или left и right, которые представляют собой индексы массива или строки.
Существует несколько способов реализации двух указателей. Для начала давайте рассмотрим следующий метод:
Указатели на краях входных данных
Перемещаем их навстречу друг другу, пока они не встретятся.
Перевод этой идеи в инструкции:
- Установите один указатель на первый индекс (0), а другой указатель на последний индекс (
input.length - 1). - Используйте цикл
while, пока указатели не станут равны друг другу. - На каждой итерации цикла перемещайте указатели навстречу друг другу. Это означает либо инкрементировать указатель, который начинался с первого индекса, либо декрементировать указатель, который начинался с последнего индекса, или и то, и другое. Решение о том, какие указатели двигать, будет зависеть от задачи, которую мы пытаемся решить.
function fn(arr):
left = 0
right = arr.length - 1
while left < right:
Do some logic here depending on the problem
Do some more logic here to decide on one of the following:
1. left++
2. right--
3. Both left++ and right--
Сила этой техники заключается в том, что у нас никогда не будет больше чем O(n) итераций для цикла while, потому что указатели начинают с расстояния n друг от друга и на каждой итерации перемещаются как минимум на один шаг ближе. Поэтому, если мы можем удерживать работу внутри каждой итерации на уровне O(1), эта техника приведет к линейному времени выполнения, что обычно является наилучшим возможным временем выполнения.
Давайте рассмотрим несколько примеров
https://leetcode.com/problems/valid-palindrome/description/
https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/