🧩 Patterns

Two Pointers

Opposite ends shrinking inward, or fast/slow on the same array

Two pointers eliminate the inner loop of brute-force O(n²) solutions. The key insight: on a sorted array you can decide which pointer to move based on the current sum/condition.

Language:
Python
Loading...

All languages — Opposite ends → shrink inward

JavaScript
function twoSumSorted(nums, target) {
  let left = 0, right = nums.length - 1;
  while (left < right) {
    const s = nums[left] + nums[right];
    if (s === target) return [left, right];
    else if (s < target) left++;
    else right--;
  }
  return [-1, -1];
}

console.log(twoSumSorted([1,2,4,6,8], 10)); // [1, 4]
TypeScript
function twoSumSorted(nums: number[], target: number): [number, number] {
  let left = 0, right = nums.length - 1;
  while (left < right) {
    const s = nums[left] + nums[right];
    if (s === target) return [left, right];
    else if (s < target) left++;
    else right--;
  }
  return [-1, -1];
}
Java
public static int[] twoSumSorted(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left < right) {
        int s = nums[left] + nums[right];
        if (s == target)       return new int[]{left, right};
        else if (s < target)   left++;
        else                   right--;
    }
    return new int[]{-1, -1};
}
Go
func twoSumSorted(nums []int, target int) (int, int) {
    left, right := 0, len(nums)-1
    for left < right {
        s := nums[left] + nums[right]
        switch {
        case s == target: return left, right
        case s < target:  left++
        default:          right--
        }
    }
    return -1, -1
}
C++
pair<int,int> twoSumSorted(vector<int>& nums, int target) {
    int left = 0, right = nums.size() - 1;
    while (left < right) {
        int s = nums[left] + nums[right];
        if (s == target)      return {left, right};
        else if (s < target)  left++;
        else                  right--;
    }
    return {-1, -1};
}