Instead of checking every pair (O(n²)), use two indices that move toward each other. One pass, one answer.
Pick a target. Left pointer starts at the smallest value, right at the largest. If the sum is too small, move left up. Too big, move right down. They meet in the middle.
Start with pointers at indices 0 and 7.
This works because the array is sorted. When the sum is too small, incrementing the left pointer is the only way to make it bigger — every value to the right of the left pointer is larger. Same logic in reverse for the right pointer. You never need to go backwards, so each element is visited at most once.
Two pointers don't always walk toward each other. Here, a "read" pointer scans forward while a "write" pointer trails behind, only advancing when it finds a new unique value.
Start. Write pointer at 0, read pointer scans from 1.
function twoPointers(arr: number[]) { let l = 0 let r = arr.length - 1 while (l < r) { // compare arr[l] and arr[r] // move l++ or r-- based on condition } }
O(n) time, O(1) space