Two Pointers Pattern

0/14 in this phase0/57 across the roadmap

šŸ“– 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:

  1. Opposite direction (converging): One at start, one at end, move inward

    • Palindrome check, two sum in sorted array, container with most water
  2. Same direction (fast-slow): Both start at beginning, one moves faster

    • Remove duplicates, partition, move zeros, linked list cycle detection
  3. 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

codeTap to expand ā›¶
1// OPPOSITE DIRECTION — Two Sum in sorted array
2function 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!
13
14// OPPOSITE — Container with most water
15function 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}
25
26// SAME DIRECTION — Remove duplicates from sorted array
27function 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 portion
37}
38
39// SAME DIRECTION — Move zeros to end
40function 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}
49
50// THREE SUM — Two pointers inside a loop
51function 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 duplicates
56 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}
70
71// IS PALINDROME — Two pointers from both ends
72function 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):

  1. Check if a string is a palindrome using two pointers
  2. Two Sum II — find pair in sorted array that sums to target
  3. Remove duplicates from sorted array in-place
  4. Move all zeros to the end maintaining order
  5. Reverse a string in-place using two pointers
  6. Valid palindrome II — can you make it palindrome by removing at most one char?
  7. Three Sum — find all unique triplets that sum to zero
  8. Container with most water — maximize area
  9. Trapping rain water — compute total trapped water
  10. 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 slow and fast naming for clarity

šŸ’¼ Interview Questions

šŸŽ¤ Mock Interview

Practice a live interview for Two Pointers Pattern