Two Pointers or N Pointers - (Theory)
-
Concept of two pointers
-
Different movement strategies
-
Operations performed when pointers are active
-
How to decide which pointer to move
-
Generalizing two pointers to n-pointers
-
Time complexity optimization using pointers
-
Algorithms and patterns derived from two pointers
1. What is the Two Pointer Technique?
The Two Pointer Technique involves using two separate indices (pointers) that traverse through a data structure (usually an array, string, or linked list) to solve problems more efficiently than brute force.
Instead of checking every possible pair (which would take O(n²)), two pointers help prune the search space by moving intelligently.
Common use cases:
-
Searching for a pair with a given sum
-
Reversing arrays or strings
-
Partitioning arrays
-
Sorting problems
-
Merging sorted arrays
2. Pointer Movement Strategies
Two pointers don’t always move the same way. There are several strategies based on the problem:
A. Toward Each Other (Converging Pointers)
Initial Setup:
i = 0,j = n - 1
When used:
-
Sorted array with target sum
-
Palindrome checks
-
Partitioning arrays
-
Min/max subarray range between i and j
Example:
while (i < j) {
int sum = arr[i] + arr[j];
if (sum == target) return true;
else if (sum < target) i++;
else j--;
}
B. Same Direction, Left to Right (Expanding)
Initial Setup:
i = 0,j = 0
When used:
-
Sliding window
-
Substring/subarray checks
-
Longest subarray with constraint
Example:
while (j < arr.length) {
// expand window
sum += arr[j];
j++;
while (sum > target) {
sum -= arr[i];
i++; // shrink window
}
// process current window
}
C. Same Direction, One From Opposite Side
Initial Setup:
i = n - 1,j = n - 2
When used:
-
Comparing elements in reverse
-
Two lists with merging logic
-
Postfix prefix alignment
D. On Two Different Structures
Example:
-
Comparing two strings, arrays, or linked lists
-
Merging two sorted lists
-
Detecting intersection in linked lists
3. Types of Operations While Pointing
When two pointers are active (e.g., i and j), the operations fall under:
A. Arithmetic Operation
-
arr[i] + arr[j] -
arr[i] * arr[j] -
Used in sum, product, average problems
B. Bitwise Operation
-
arr[i] ^ arr[j] -
Useful in XOR pair problems, subset masks
C. Decision Based on Pointed Values
-
If
arr[i] == arr[j], we may expand/shrink window -
If string
s.charAt(i) == t.charAt(j) -
Used in palindrome checking, pointer matching problems
4. How to Decide Which Pointer to Move
There are generally three approaches:
A. Move based on ordering
-
If
arr[i] + arr[j] < target, movei++ -
Else move
j-- -
Used in sorted arrays when finding pair sum
B. Move based on window constraints
-
Move right pointer to expand
-
Move left pointer to shrink window
-
Used in sliding window problems
C. Move based on matching condition
-
If elements match, advance both
-
Else, either backtrack or move one side
-
Used in string matching, two arrays comparison, linked list intersection
5. How to Generalize to N Pointers
N-Pointer Strategy:
When a problem requires more than two elements to be processed simultaneously (e.g., triplet or quadruplet problems), two-pointer logic can be extended:
Three Pointer (Triple Nested Logic)
-
Fix one pointer, apply two-pointer on the rest
-
Used in 3Sum, 3-way partitioning
for (int i = 0; i < n - 2; i++) {
int left = i + 1, right = n - 1;
while (left < right) {
int sum = arr[i] + arr[left] + arr[right];
// logic
}
}
Four Pointer
-
Nested two loops + inner two-pointer logic
-
Used in 4Sum, subset sum with constraints
K-Pointer (Recursive Generalization)
-
Fix
k - 2elements and use 2 pointers for the rest -
Implemented with backtracking or recursion
6. How Two Pointers Help Reduce Time Complexity
| Naive Approach | Two-Pointer Approach |
|---|---|
| O(n²) for pair sum | O(n) for sorted array |
| O(n³) for triplets | O(n²) with two-pointer on sorted array |
| O(n) sliding window | O(1) amortized per operation |
How it works:
-
Avoids unnecessary repeated computation
-
Exploits properties of sorted order or problem constraints
-
Processes the array linearly or log-linearly
7. Algorithms & Patterns Derived from Two Pointers
A. Binary Search
-
One pointer as
low, one ashigh -
Each iteration halves the search space
-
Time: O(log n)
B. Sliding Window
-
Left and right pointers move in the same direction
-
Maintain a dynamic window to satisfy a condition
-
Used in subarrays/substrings with constraints
-
Time: O(n)
C. Two Sum / K Sum Patterns
-
Sorted array → use two pointers
-
Unsorted → use HashSet
-
2Sum: O(n) (sorted)
-
3Sum: O(n²)
-
4Sum: O(n³)
D. Fast and Slow Pointers
-
Used in cycle detection (LinkedList, arrays)
-
Floyd’s Tortoise and Hare algorithm
-
Time: O(n), Space: O(1)
E. Merge Algorithms
-
Merge two sorted arrays/lists using two pointers
-
Efficient for external sorting, merge sort
F. Palindrome and Symmetric Checks
-
Compare characters from both ends
-
Time: O(n)
G. Intersection/Union of Two Sorted Arrays
-
Use two pointers to iterate and compare both arrays
-
Time: O(n + m)
H. Partitioning and Dutch National Flag Algorithm
-
Three pointers: low, mid, high
-
Used in sorting 0s, 1s, and 2s
I. Substring/Anagram Matching
-
Sliding window + hash map
-
Two pointers define the range being examined
Conclusion
The Two Pointer Technique is one of the most versatile and foundational strategies in problem-solving. Once mastered, it unlocks the ability to optimize brute force solutions and build efficient algorithms for:
-
Arrays
-
Strings
-
Linked Lists
-
Interval problems
-
Graph problems with BFS-like pointer expansion
It also serves as a foundation for advanced strategies like:
-
Binary Search on Answers
-
Sliding Window Optimizations
-
Recursive K-Sum extensions
-
Monotonic Queue (a form of sliding window + two-pointer)