Two Pointers

Two Pointers

Replace O(n²) brute force with intelligent pointer movement. Works on sorted arrays and linked lists.

Two Sum (Opposite Ends) — Step by Step

Target: find two numbers that sum to target. Array is sorted.

LEFT pointer RIGHT pointer FOUND
Press Start to begin.
Fast & Slow Pointer — Remove Duplicates

Slow = boundary of result. Fast = scanner for unique elements.

SLOW FAST
Press Animate to see slow/fast pointers in action.

Pattern 1 — Opposite Ends

When to use
  • Array is sorted
  • Find pair satisfying a condition (sum = target, product, etc.)
  • Valid Palindrome, Container With Most Water
Core Logic
Start left=0, right=n-1. Check sum: too big → move right inward (decreases sum). Too small → move left inward (increases sum). Works because array is sorted — moving a pointer gives guaranteed information.
Critical Bug
Use left < right, NOT left <= right. When both point to same element, pairing it with itself is invalid.

Pattern 2 — Fast & Slow (Same Direction)

When to use
  • Remove duplicates in-place from sorted array
  • Cycle detection in linked list (Floyd's algorithm)
  • Find middle of linked list
  • Partition array in-place
Core Logic
Slow pointer = boundary of "result so far". Fast pointer = scanner that finds next valid element. When fast finds something valid, slow advances and copies.

Pattern 1 — Two Sum (Sorted)

def two_sum_sorted(arr, target):
    left, right = 0, len(arr) - 1
    while left < right:         # NOT <=
        s = arr[left] + arr[right]
        if   s == target: return [left, right]
        elif s <  target: left  += 1  # need bigger
        else:             right -= 1  # need smaller
    return []

# Valid Palindrome
def is_palindrome(s):
    l, r = 0, len(s) - 1
    while l < r:
        if s[l] != s[r]: return False
        l += 1; r -= 1
    return True

Pattern 2 — Fast & Slow

# Remove duplicates from sorted array in-place
def remove_dupes(arr):
    if not arr: return 0
    slow = 0
    for fast in range(1, len(arr)):
        if arr[fast] != arr[slow]:
            slow += 1
            arr[slow] = arr[fast]
    return slow + 1

# 3Sum — sort + two pointers for each anchor
def three_sum(nums):
    nums.sort(); res = []
    for i in range(len(nums) - 2):
        if i > 0 and nums[i] == nums[i-1]: continue
        l, r = i+1, len(nums)-1
        while l < r:
            s = nums[i]+nums[l]+nums[r]
            if   s == 0: res.append([nums[i],nums[l],nums[r]]); l+=1; r-=1
            elif s <  0: l += 1
            else:         r -= 1
    return res

LeetCode Problems

  • EasyValid PalindromeOpposite ends
  • EasySquares of Sorted ArrayOpposite ends, fill from right
  • MediumTwo Sum II (sorted)Opposite ends
  • Medium3SumAnchor + two pointers
  • MediumContainer With Most WaterOpposite ends, keep larger side
  • MediumRemove Duplicates from Sorted ArrayFast & slow
  • HardTrapping Rain WaterTwo pointers with max tracking