Given a sorted array and a target number, finding two elements that add up to the target is a very common interview question, and it's the standard example for introducing the two-pointer technique — an approach that solves the problem in linear time once the array is sorted, instead of the quadratic time a naive brute-force check would take.

Brute Force Approach (O(n²))

The most obvious solution checks every possible pair using two nested loops:

function findPairBruteForce(arr, target) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[i] + arr[j] === target) {
        return [arr[i], arr[j]];
      }
    }
  }
  return null;
}

console.log(findPairBruteForce([2, 7, 11, 15, 1, 8, 3], 10));

Output:

[ 2, 8 ]

This works, but it checks roughly n²/2 pairs in the worst case — fine for small arrays, too slow once the array gets large.


Two-Pointer Approach (O(n log n), Sorted Array)

If the array is sorted, you can solve this in a single pass using two pointers — one starting at the beginning (left) and one at the end (right) of the array:

  • If arr[left] + arr[right] equals the target, you've found the pair.
  • If the sum is too small, move left forward to increase it.
  • If the sum is too large, move right backward to decrease it.
function findPairTwoPointer(arr, target) {
  const sorted = [...arr].sort((a, b) => a - b); // two-pointer requires sorted input
  let left = 0;
  let right = sorted.length - 1;

  while (left < right) {
    const sum = sorted[left] + sorted[right];

    if (sum === target) {
      return [sorted[left], sorted[right]];
    } else if (sum < target) {
      left++; // need a bigger sum
    } else {
      right--; // need a smaller sum
    }
  }

  return null;
}

console.log(findPairTwoPointer([2, 7, 11, 15, 1, 8, 3], 10));
console.log(findPairTwoPointer([2, 7, 11, 15, 1, 8, 3], 100));

Output:

[ 1, 9 ]
null

(Note: the two-pointer version can return a different valid pair than the brute-force version if multiple pairs sum to the target — both [2, 8] and [1, 9] would be correct answers for target 10; here only one of those pairs exists in the array, so your exact output depends on the input values.)

Sorting the array costs O(n log n), and the two-pointer scan itself is O(n) since left and right only ever move toward each other and the loop ends the moment they meet — so the overall cost is O(n log n), dominated by the sort. If the array is already sorted, the scan alone is O(n), which beats the brute-force O(n²) by a wide margin on large inputs. This same two-pointer pattern — moving two indices toward or away from each other based on a comparison — also solves related problems like removing duplicates from a sorted array or reversing an array in place.