Two Pointers Pattern
š Concept
The two pointers technique uses two references to iterate through a data structure, usually moving toward each other or in the same direction. It often reduces O(n²) to O(n).
Three types of two pointers:
Opposite direction (converging): One at start, one at end, move inward
- Palindrome check, two sum in sorted array, container with most water
Same direction (fast-slow): Both start at beginning, one moves faster
- Remove duplicates, partition, move zeros, linked list cycle detection
Sliding window (covered in next topic): Left and right define a window
- Max sum subarray, longest substring, minimum window
When to recognize two pointers:
- Array is SORTED and you need to find pairs
- Need to compare elements from both ends
- Need to partition or rearrange in-place
- Need to process elements with O(1) extra space
š Real-world analogy: Two pointers is like squeezing toothpaste ā one hand at the bottom, one hand moves toward it. Or like two people searching a hallway from opposite ends ā they meet somewhere in the middle.
š» Code Example
1// OPPOSITE DIRECTION ā Two Sum in sorted array2function twoSumSorted(arr: number[], target: number): [number, number] | null {3 let left = 0, right = arr.length - 1;4 while (left < right) {5 const sum = arr[left] + arr[right];6 if (sum === target) return [left, right];7 if (sum < target) left++;8 else right--;9 }10 return null;11}12// O(n) time, O(1) space ā vs O(n²) brute force!1314// OPPOSITE ā Container with most water15function maxArea(height: number[]): number {16 let left = 0, right = height.length - 1, maxWater = 0;17 while (left < right) {18 const water = Math.min(height[left], height[right]) * (right - left);19 maxWater = Math.max(maxWater, water);20 if (height[left] < height[right]) left++;21 else right--;22 }23 return maxWater;24}2526// SAME DIRECTION ā Remove duplicates from sorted array27function removeDuplicates(nums: number[]): number {28 if (nums.length === 0) return 0;29 let slow = 0;30 for (let fast = 1; fast < nums.length; fast++) {31 if (nums[fast] !== nums[slow]) {32 slow++;33 nums[slow] = nums[fast];34 }35 }36 return slow + 1; // Length of unique portion37}3839// SAME DIRECTION ā Move zeros to end40function moveZeros(nums: number[]): void {41 let insertPos = 0;42 for (let i = 0; i < nums.length; i++) {43 if (nums[i] !== 0) {44 [nums[insertPos], nums[i]] = [nums[i], nums[insertPos]];45 insertPos++;46 }47 }48}4950// THREE SUM ā Two pointers inside a loop51function threeSum(nums: number[]): number[][] {52 nums.sort((a, b) => a - b);53 const result: number[][] = [];54 for (let i = 0; i < nums.length - 2; i++) {55 if (i > 0 && nums[i] === nums[i - 1]) continue; // Skip duplicates56 let lo = i + 1, hi = nums.length - 1;57 while (lo < hi) {58 const sum = nums[i] + nums[lo] + nums[hi];59 if (sum === 0) {60 result.push([nums[i], nums[lo], nums[hi]]);61 while (lo < hi && nums[lo] === nums[lo + 1]) lo++;62 while (lo < hi && nums[hi] === nums[hi - 1]) hi--;63 lo++; hi--;64 } else if (sum < 0) lo++;65 else hi--;66 }67 }68 return result;69}7071// IS PALINDROME ā Two pointers from both ends72function isPalindrome(s: string): boolean {73 const clean = s.toLowerCase().replace(/[^a-z0-9]/g, '');74 let l = 0, r = clean.length - 1;75 while (l < r) {76 if (clean[l] !== clean[r]) return false;77 l++; r--;78 }79 return true;80}
šļø Practice Exercise
Practice Problems (Easy ā Hard):
- Check if a string is a palindrome using two pointers
- Two Sum II ā find pair in sorted array that sums to target
- Remove duplicates from sorted array in-place
- Move all zeros to the end maintaining order
- Reverse a string in-place using two pointers
- Valid palindrome II ā can you make it palindrome by removing at most one char?
- Three Sum ā find all unique triplets that sum to zero
- Container with most water ā maximize area
- Trapping rain water ā compute total trapped water
- Sort colors (Dutch National Flag) ā three-way partition
ā ļø Common Mistakes
Applying two pointers to unsorted arrays when the approach requires sorted input
Not handling duplicates in three sum ā must skip duplicate values to avoid duplicate triplets
Moving the wrong pointer ā in converging two pointers, move the pointer that's 'less optimal'
Not recognizing two pointers pattern ā keywords: 'sorted array', 'pair', 'in-place', 'O(1) space'
Off-by-one with same-direction pointers ā use
slowandfastnaming for clarity
š¼ Interview Questions
š¤ Mock Interview
Practice a live interview for Two Pointers Pattern