Two Pointers is a powerful problem-solving pattern where you initialize two variables and move them towards each other, away from each other, or in the same direction, based on the problem.
Using this approach, you can reduce the time complexity of many array and string related problems from O(n²) to O(n).
In this chapter, I’ll break down:
Let's first understand what a pointer is.
A pointer is simply a variable that represents an index or position within a data structure, such as an array or linked list.
Using pointers at different positions, we can efficiently compare elements and make decisions without relying on nested loops, which would otherwise lead to O(n²) time complexity.
The Two Pointers technique can be applied in different ways depending on the problem.
Let’s explore the three most common strategies.
In this approach, pointers start at opposite ends of a data structure and move inward toward each other.
The pointers adjust their positions based on comparisons, until a certain condition is met, or they cross each other.
This strategy is ideal for problems where we need to compare elements from opposite ends of an array or string for example: checking if a string is a palindrome
A palindrome is a word, phrase, or sequence that reads the same forward and backward (e.g., "racecar", "madam").
To check if a string is a palindrome, we:
Initialize two pointers: one at the beginning and one at the end.
Compare characters at both pointers:
false.Repeat until the pointers meet.
In this approach, both pointers start at the same end (usually the beginning) and move in the same direction.
These pointers generally serve two different but complementary roles:
Here are the two popular variations of this approach:
In this approach, we move the first pointer independently until it finds an element that meets a certain condition.
After this, we start traversing with the second pointer to find additional information related to what the first pointer found.
This technique is particularly useful when we need to process elements in stages or maintain a fixed distance between two pointers.
A good example of this approach is finding the Nth node from the end of a linked list.
Nth node, initialize the second pointer at the head.A Two-Pointer algorithm is generally applied to linear data structures, such as: array, strings or linked lists.
A strong clue that a problem can be solved using the Two Pointers technique is if the input data follows a predictable pattern—such as sorted array or palindromic string.
For example, in a sorted array, moving a pointer to the right ensures you are always moving to a greater or equal value, making it easy to compare the values at both the pointers.
Another strong indicator that a problem can be solved using Two Pointers is when it explicitly asks for: