The two-pointer technique is a powerful trick, but it does not fit every problem. There is a small, friendly family of problems where you can apply it *directly* — no clever twists needed. These are usually the easy problems where you walk through an array from both ends at the same time and meet in the middle.
Here is the simple test. If a problem (or its solution) matches this pattern, two pointers will work directly:
> Given an array arr, do something with arr[i] and arr[j] where i < j. With each step, i and j move closer to each other. They can start at any two positions x and y as long as x < y.
Think of two people standing at opposite ends of a row of boxes, walking toward each other and doing a little task at each box until they meet. That mental picture *is* the two-pointer technique.
We are given an array arr and we must reverse it. The catch is the words *in-place*. In-place means we change the original array directly — we are not allowed to build a brand-new array and hand that back instead. We must flip the same array around.
For example, the array:
1 2 3 4 5 6 7 8
should become:
8 7 6 5 4 3 2 1
The first element becomes the last, the second becomes the second-last, and so on.
The most obvious idea uses a helper. We make a second array called temp:
arr backwards (from the last index to the first) and copy each value into temp from front to back. Now temp holds the reversed order.temp forwards and copy everything back into arr.Here is the C++ version:
void reverse(vector<char>& arr) {
// Create temp array to store reverse
vector<char> temp(arr.size());
int lastIndex = arr.size() - 1;
// Traverse arr in reverse direction and copy to temp
for (int i = lastIndex; i >= 0; i--) {
temp[lastIndex - i] = arr[i];
}
// Copy temp back to arr
for (int i = 0; i <= lastIndex; i++) {
arr[i] = temp[i];
}
}
This works correctly, but notice the cost. It walks the data twice, and it needs a whole extra array temp of the same size. That extra memory is wasted effort — we can do better.
Here is the key insight. To reverse an array, you do not need a second array at all. You just need to swap pairs of elements that are the same distance from each end: the first with the last, the second with the second-last, and so on.
So we set up two pointers (really just two index variables):
left starts at 0 (the very first index).right starts at n - 1 (the very last index), where n is the size of the array.Then we repeat the following while left < right:
arr[left] and arr[right].left one step forward (left++).right one step backward (right--).When left and right meet in the middle, every pair has been swapped and the array is fully reversed.
Let's watch it on 1 2 3 4 5 6 7 8:
0 and index 7: 8 2 3 4 5 6 7 11 and index 6: 8 7 3 4 5 6 2 12 and index 5: 8 7 6 4 5 3 2 13 and index 4: 8 7 6 5 4 3 2 1Now left and right have crossed, so we stop. Done — and we never touched a second array.
Here is the code:
void reverse(vector<int> &arr) {
// Initialize two pointers, one pointing to the beginning of the
// array and the other pointing to the end of the array
int left = 0;
int right = arr.size() - 1;
// Use a while loop to traverse the array using the two pointers
while (left < right) {
// Swap the values pointed by the left and right pointers
swap(arr[left], arr[right]);
// Move the pointers towards the center of the array
left++;
right--;
}
}
Compare it back to our test:
arr[i] and arr[j] is swap.left < right (that is i < j).x = 0 and y = arr.length - 1.It matches line for line, which is exactly why we can apply two pointers *directly*. The payoff is real: we reverse the array in a single pass and use no extra space, beating the brute-force version on both counts.
Once you recognize the "meet in the middle" shape, a whole set of easy problems opens up. A few you can solve the same way:
Each one is just a different small task done at arr[left] and arr[right] while the two pointers walk toward each other.