The 10 Variations of Two Pointers for Interview Preparation
Hey everyone! While most people focus on learning complex algorithms like DP and graphs, they often overlook one of the simplest yet most powerful patterns - Two Pointers. This might be because it seems too basic, or people don't realize how versatile it is. However, mastering two pointers can help you solve 15-20% of all interview problems with elegant O(n) solutions. It's one of the highest ROI patterns you can learn! So let me show you why two pointers deserves way more respect than it gets.
Variation 1: Opposite Direction (Converging)
When to use: Sorted array, palindrome checking, pair sum problems
Movement: Start from both ends, move toward center
Template:
int left = 0, right = arr.length - 1;
while (left < right) {
// Process arr[left] and arr[right]
if (condition) {
left++;
} else {
right--;
}
}Classic Problems:
- Two Sum II - Input Array Is Sorted
- Valid Palindrome
- Container With Most Water
- Reverse String
- Remove Duplicates from Sorted Array
Why it works: When array is sorted or has symmetric property, we can eliminate half the search space with each decision.
Variation 2: Same Direction (Fast & Slow)
When to use: Remove elements, in-place modifications, partitioning
Movement: Both move forward, one faster than the other
Template:
int slow = 0;
for (int fast = 0; fast < arr.length; fast++) {
if (shouldKeep(arr[fast])) {
arr[slow] = arr[fast];
slow++;
}
}
return slow; // new lengthClassic Problems:
Why it works: Fast pointer explores, slow pointer maintains the valid portion.
Variation 3: Sliding Window
When to use: Subarray/substring with constraints, variable window size
Movement: Expand right, shrink left when condition violated
Template:
int left = 0, right = 0;
while (right < arr.length) {
// Add arr[right] to window
right++;
while (windowInvalid) {
// Remove arr[left] from window
left++;
}
// Update result with current window
}Classic Problems:
- Longest Substring Without Repeating Characters
- Minimum Size Subarray Sum
- Longest Substring with At Most K Distinct Characters
Why it works: Maintains a valid window by expanding and contracting dynamically.
Variation 4: Partitioning (Dutch National Flag)
When to use: Sort into groups, 3-way partitioning
Movement: Three pointers - low, mid, high
Template:
int low = 0, mid = 0, high = arr.length - 1;
while (mid <= high) {
if (arr[mid] == 0) {
swap(arr, low, mid);
low++;
mid++;
} else if (arr[mid] == 1) {
mid++;
} else {
swap(arr, mid, high);
high--;
}
}Classic Problems:
- Sort Colors
- Sort Array By Parity
- Partition Array
Why it works: Maintains three regions - processed, current, and unprocessed.
Variation 5: Merge Two Sorted Arrays
When to use: Merging sorted sequences, finding common elements
Movement: One pointer per array, advance smaller element
Template:
int i = 0, j = 0;
while (i < arr1.length && j < arr2.length) {
if (arr1[i] < arr2[j]) {
// Process arr1[i]
i++;
} else if (arr1[i] > arr2[j]) {
// Process arr2[j]
j++;
} else {
// Both equal
i++;
j++;
}
}
// Handle remaining elementsClassic Problems:
- Merge Sorted Array
- Intersection of Two Arrays
- Intersection of Two Arrays II
- Median of Two Sorted Arrays
Why it works: Sorted property allows us to always know which element to process next.
Variation 6: Pair Sum (Multiple Pointers)
When to use: Finding pairs/triplets with target sum
Movement: Fix one, use two pointers for remaining
Template:
// For 3Sum
Arrays.sort(nums);
for (int i = 0; i < nums.length - 2; i++) {
int left = i + 1, right = nums.length - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (sum == target) {
// Found triplet
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}Classic Problems:
Why it works: Sorted array + two pointers eliminates duplicate work.
Variation 7: Reverse/Rotate
When to use: In-place array/string reversal, rotation
Movement: Swap from both ends moving toward center
Template:
void reverse(int[] arr, int start, int end) {
while (start < end) {
swap(arr, start, end);
start++;
end--;
}
}
// Rotate array: reverse(0, k-1), reverse(k, n-1), reverse(0, n-1)Classic Problems:
Why it works: Swapping from ends naturally reverses order.
Variation 8: Trapping Water / Histogram
When to use: Area/volume calculations, optimization problems
Movement: Two pointers with auxiliary variables tracking max/min
Template:
int left = 0, right = arr.length - 1;
int leftMax = 0, rightMax = 0, result = 0;
while (left < right) {
if (arr[left] < arr[right]) {
if (arr[left] >= leftMax) {
leftMax = arr[left];
} else {
result += leftMax - arr[left];
}
left++;
} else {
if (arr[right] >= rightMax) {
rightMax = arr[right];
} else {
result += rightMax - arr[right];
}
right--;
}
}Classic Problems:
Why it works: Process from both ends, always move the pointer with smaller value.
Variation 9: Subsequence Matching
When to use: Check if one sequence is subsequence of another
Movement: One pointer per string, advance first when match found
Template:
int i = 0; // pointer for subsequence
for (int j = 0; j < str.length() && i < subseq.length(); j++) {
if (str.charAt(j) == subseq.charAt(i)) {
i++;
}
}
return i == subseq.length(); // all matchedClassic Problems:
Why it works: Greedily match characters in order they appear.
Variation 10: Interval Merging with Pointers
When to use: Merging overlapping intervals, range operations
Movement: Iterate with pointer, merge based on overlap
Template:
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
List<int[]> result = new ArrayList<>();
int[] current = intervals[0];
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] <= current[1]) {
// Overlap - merge
current[1] = Math.max(current[1], intervals[i][1]);
} else {
// No overlap
result.add(current);
current = intervals[i];
}
}
result.add(current);Classic Problems:
Why it works: Sorted intervals allow sequential merging.
📊 Complete Problem List (By Difficulty)
- Two Sum II
- Valid Palindrome
- Remove Element
- Remove Duplicates from Sorted Array
- Reverse String
- Squares of a Sorted Array
- Move Zeroes
- Merge Sorted Array
- Is Subsequence
- Reverse Vowels of a String
- 3Sum
- Container With Most Water
- Sort Colors
- 3Sum Closest
- 4Sum
- Remove Duplicates from Sorted Array II
- Rotate Array
- Reverse Words in a String
- Partition Labels
- Valid Triangle Number
- Minimum Size Subarray Sum
- Number of Subsequences That Satisfy Sum Condition
- Trapping Rain Water
- Minimum Window Substring
- Substring with Concatenation of All Words
- Median of Two Sorted Arrays
Master two pointers, and you'll solve problems others struggle with using complex hash maps or nested loops - with cleaner code and better complexity!
Related Posts
Check out my posts which may help you in your preparation :
- 13 DP Patterns for Interview Preparation
- 10 Dijkstra Variations for Interview Preparation
- Understanding Time Complexity: The 10^8 Operations Rule
- 10 Essential Design Problems for DSA Interviews
- Essential CS Fundamental Topics For Interviews
- Essential Graph Patterns for Coding Interviews
- Essential String Patterns for Coding Interviews
- 15 Essential DSA Patterns for Tech Interviews
What's your favorite two pointer problem? Or which variation do you find trickiest? Let's discuss! 👇

