We are familiar with frequency counting — counting elements in arrays or strings using hash maps or buckets. It’s a powerful tool, but as problems grow, relying solely on extra space can be limiting. That’s when the Two Pointer technique comes to the rescue: a space-efficient, intuitive way to traverse arrays or strings for many common problems.
In this article, we’ll explore what Two Pointer is, when to use it, types of problems it fits, and how to start practicing it today.
🔹 Frequency Count: The Warm-Up
Most beginner array problems use frequency counts:
vector<int> arr = {1,1,2,2,2,3};
unordered_map<int,int> freq;
for(int x : arr) freq[x]++; // Count occurrences
for(auto [val, count] : freq) {
cout << val << " appears " << count << " times\n";
}
This works great, but it uses extra space (O(n) for the map), and sometimes, we can solve problems in-place without extra memory using pointers.
That’s where Two Pointer technique shines.
🔹 What is Two Pointer Technique?
Two Pointer is using two indices instead of one to traverse an array, string, or linked list.
Why use it?
- Reduce time complexity (often O(n² → O(n))
- Avoid extra memory
- Handle subarrays, pairs, or symmetrical checks efficiently
Think of it as moving pointers smartly based on conditions, instead of blindly iterating every element.
🔹 When to Think Two Pointer?
Ask yourself these questions:
✅ Is the problem on array / string / list?
✅ Is it sorted or can it be sorted?
✅ Are you asked about pairs, ranges, windows, or symmetry?
✅ Can you avoid nested loops with clever pointer movement?
If most answers are YES, Two Pointer is likely the right approach.
Keywords to spot:
“Two numbers sum to K” → left/right pointers
“Palindrome” → left/right pointers
“Remove duplicates” → slow/fast pointer
“Longest substring” → sliding window
“Merge arrays” → left/right pointers
🔹 Three Main Types of Two Pointer Problems
1️⃣ Opposite Direction (Left ↔ Right)
Pattern:
L → ← R
Used for:
- Sorted arrays
- Symmetry or pair checks
Typical problems:
- Two Sum (sorted array)
- Palindrome check
- Container With Most Water
Mental Rule:
- Sum too small → move left
- Sum too big → move right
Example:
int l = 0, r = n-1;
while(l < r) {
int sum = arr[l] + arr[r];
if(sum == target) return true;
else if(sum < target) l++;
else r--;
}
2️⃣ Same Direction (Slow & Fast)
Pattern:
slow →
fast → →
Used for:
- Modifying array/string in-place
- Skipping or filtering elements
Typical problems:
- Remove duplicates
- Remove specific element
- Move zeros
- Compress string
Mental Rule:
- Fast explores
- Slow writes the valid elements
Example:
int slow = 0;
for(int fast = 0; fast < n; fast++) {
if(arr[fast] != val) arr[slow++] = arr[fast];
}
3️⃣ Sliding Window (Expandable & Shrinkable)
Pattern:
L → → → R
Used for:
- Subarrays or substrings
- Conditions like sum, count, unique characters
- Typical problems:
- Longest substring without repeating characters
- Minimum window substring
- Subarray with sum ≤ K
Mental Rule:
- Expand to include elements
- Shrink to satisfy condition
🔹How to Identify Two Pointer Problems Quickly
Checklist:
- Is it array/string?
- Can you avoid nested loops?
- Can pointer movement depend on condition?
- Is sorting allowed?
- Is answer based on pairs/range/window?
If 3+ YES, it’s likely a Two Pointer problem.
🔹Beginner Mistakes to Avoid
❌ Using pointers on unsorted arrays blindly
❌ Moving both pointers without logic
❌ Forgetting while(l < r) condition
❌ Confusing sliding window with opposite pointer approach
🔹How to Practice Effectively
- Identify the pattern first (no coding)
- Write pointer movement rules in plain English
- Code it
- Compare with solution
- Rewrite from memory
This reinforces logic, not just syntax.
🔹 Starter Practice Set
Try these in order:
- Reverse string
- Valid palindrome
- Two Sum (sorted array)
- Remove duplicates from sorted array
- Move zeros
- Container With Most Water
- Longest substring without repeating characters
🌱 Final Thought
Two Pointer isn’t about syntax.
It’s about smart pointer movement:
“If condition improves → move this pointer
If condition worsens → move the other pointer”
Master this, and many array problems become simple, elegant, and efficient.
Top comments (0)