Skip to main content

๐Ÿ‘‰๐Ÿ‘ˆ Two Pointers

Conceptโ€‹

The Two Pointers pattern uses two index variables that move through the array (or string) โ€” either toward each other (opposite direction) or in the same direction (fast/slow pointers).

It eliminates the need for nested loops, reducing O(nยฒ) brute-force solutions to O(n).


When to Useโ€‹

  • The array/string is sorted (or sorting it first is allowed)
  • You're looking for pairs or triplets that satisfy a condition
  • You need to partition or remove elements in-place
  • The problem mentions "two numbers that sum to target"
  • Detecting cycles in a linked list (fast/slow pointer variant)

Types of Two Pointersโ€‹

Type 1: Opposite Direction (Converging)โ€‹

[1, 2, 3, 4, 5, 6]
โ†‘ โ†‘
left right

Both pointers start at opposite ends and move inward.

Type 2: Same Direction (Fast & Slow)โ€‹

[1, 2, 3, 4, 5, 6]
โ†‘ โ†‘
slow fast

One pointer runs ahead; the slow pointer marks where valid elements go.


Java Templateโ€‹

// ---- Type 1: Converging (sorted array) ----
public boolean hasPairWithSum(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == target) return true;
else if (sum < target) left++;
else right--;
}
return false;
}

// ---- Type 2: Fast/Slow (remove duplicates in-place) ----
public int removeDuplicates(int[] nums) {
int slow = 0;
for (int fast = 1; fast < nums.length; fast++) {
if (nums[fast] != nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1; // new length
}

Worked Example: 3Sumโ€‹

Problem: Find all unique triplets in an unsorted array that sum to zero.

Approach:

  1. Sort the array โ†’ enables two-pointer on the inner pair
  2. For each element nums[i], use two pointers for the remaining subarray
  3. Skip duplicates to avoid repeated triplets
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<>();

for (int i = 0; i < nums.length - 2; i++) {
// Skip duplicate values for the first element
if (i > 0 && nums[i] == nums[i - 1]) continue;

int left = i + 1, right = nums.length - 1;

while (left < right) {
int sum = nums[i] + nums[left] + nums[right];

if (sum == 0) {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
// Skip duplicates for left and right
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
} else if (sum < 0) {
left++;
} else {
right--;
}
}
}
return result;
}

Trace for [-1, 0, 1, 2, -1, -4]:

After sort: [-4, -1, -1, 0, 1, 2]

i=0 (โˆ’4): left=1, right=5 โ†’ sum=โˆ’4+(โˆ’1)+2=โˆ’3 < 0 โ†’ left++
left=2, right=5 โ†’ sum=โˆ’4+(โˆ’1)+2=โˆ’3 < 0 โ†’ left++
left=3, right=5 โ†’ sum=โˆ’4+0+2=โˆ’2 < 0 โ†’ left++
left=4, right=5 โ†’ sum=โˆ’4+1+2=โˆ’1 < 0 โ†’ left++
left=5 โ‰ฅ right โ†’ stop

i=1 (โˆ’1): left=2, right=5 โ†’ sum=โˆ’1+(โˆ’1)+2=0 โœ“ โ†’ add [โˆ’1,โˆ’1,2]
skip dup for left, right โ†’ left=3, right=4
sum=โˆ’1+0+1=0 โœ“ โ†’ add [โˆ’1,0,1]

i=2 (โˆ’1): skip (dup of i=1)
...
Result: [[-1,-1,2], [-1,0,1]]

Time: O(nยฒ) | Space: O(1) (ignoring output)


Common Mistakesโ€‹

MistakeFix
Not sorting firstSort when using converging two pointers
Off-by-one: left < right vs left <= rightUse < for pairs, <= only when single element is valid
Missing duplicate skipAfter finding a result, advance past all duplicates
Forgetting inner loop advancesBoth left++ AND right-- after a match

LeetCode Problemsโ€‹

๐ŸŸข Easyโ€‹

#ProblemType
125Valid PalindromeConverging
167Two Sum II - Input Array is SortedConverging
283Move ZeroesFast/Slow
344Reverse StringConverging
977Squares of a Sorted ArrayConverging

๐ŸŸก Mediumโ€‹

#ProblemType
11Container With Most WaterConverging
153SumSort + converging
163Sum ClosestSort + converging
184SumSort + two loops + converging
75Sort Colors3-way partition (Dutch flag)
80Remove Duplicates IIFast/Slow
142Linked List Cycle IIFast/Slow on list
986Interval List IntersectionsTwo list pointers

๐Ÿ”ด Hardโ€‹

#ProblemType
42Trapping Rain WaterConverging with max tracking
76Minimum Window SubstringSliding window variant