Pointers Moving Inward

Core10 min

Two pointers can process a sequence from opposite ends when one step can finish work at both boundaries. Suppose we want to reverse [1, 2, 3, 4, 5] in place. The value at the beginning belongs at the end, and the value at the end belongs at the beginning, so swap those two values first. The outer positions are then finished and never need to change again. The next unfinished pair is one position closer to the center.

Let left point to the first position not yet finished and right point to the last. They begin at the first and last indices: left = 0 and right = n - 1. Swap values[left] and values[right], then move both pointers inward with left += 1 and right -= 1. Repeat while left < right.

The loop stops when the pointers meet or cross. At that point, there is no unfinished pair left. If the sequence has an odd length, the middle value does not need to move because reversing the sequence leaves it in the same position.

Which positions are still unfinished?

1 / 3
Step 1 of 3.
The pointers begin at indices 0 and 4. These are the first two positions to swap.

The useful idea is not that two-pointer algorithms always move both pointers. Both move here because the same swap finishes both boundary positions. In another problem, one comparison may finish only one boundary, so only the pointer at that boundary should move. Pointer movement must follow from what the current step has proved.

Why do both pointers move after a swap?
1def reverse_values(values: list[int]) -> None:
2 left = 0
3 right = len(values) - 1
4
5 while left < right:
6 values[left], values[right] = values[right], values[left]
7 left += 1
8 right -= 1

This pattern applies when one step completely handles both ends of the remaining range. Reverse String uses it directly. Palindrome checking also compares both ends, although it stops early if a pair does not match.

Time: O(n)Space: O(1)

The loop performs ⌊n / 2⌋ swaps, and each swap takes constant time, so the total time is O(n). The algorithm stores only the two indices and constant temporary storage, so it uses O(1) auxiliary space.