This looks like Two Sum, but the array being sorted is the whole point: it means we don’t need a hash map to find the partner value, because we can reason about which direction to move using the order of the elements. That’s what unlocks the O(1)-extra-space requirement the problem asks for.
Brute Force
Time O(n²)Space O(1)Ignore the fact that the array is sorted and check every pair, same as the original Two Sum. It’s guaranteed to find the unique pair, but it never uses the ordering information the problem hands us for free.
class Solution: def twoSum(self, numbers: list[int], target: int) -> list[int]: n = len(numbers) for i in range(n): for j in range(i + 1, n): if numbers[i] + numbers[j] == target: return [i + 1, j + 1] return []Why it’s slow: it re-derives the same information a sorted array already gives us — for a sorted array we can tell instantly whether a candidate sum is too big or too small, but this approach throws that signal away and just brute-forces every pair.
Two Pointers (Converging)
OptimalTime O(n)Space O(1)Put one pointer l at the start and one pointer r at the end. Because the array is sorted, the sum numbers[l] + numbers[r] moves in a predictable direction: if it’s too big, the only way to shrink it is to pull r left (every element left of r is <= numbers[r]); if it’s too small, the only way to grow it is to push l right. So at every step exactly one move is correct, and we never need to backtrack or remember anything beyond the two pointers.
class Solution: def twoSum(self, numbers: list[int], target: int) -> list[int]: l, r = 0, len(numbers) - 1 while l < r: total = numbers[l] + numbers[r] if total == target: return [l + 1, r + 1] elif total < target: l += 1 else: r -= 1 return []Tracing numbers = [1, 3, 4, 5, 7, 10, 11], target = 9:
1 + 11 = 12 > 9. Too big — move r left.
Correctness: if numbers[l] + numbers[r] > target, then pairing numbers[r] with anything to the right of l is even worse (the array is non-decreasing), so r is the only index that can safely move — and symmetrically for the too-small case. This means the converging scan can never skip past the true answer: whichever pointer would need to move to reach it is exactly the one the algorithm moves.
Complexity: l and r each move at most n times total and the loop stops as soon as they meet, so the whole array is scanned once → O(n) time. Only two index variables are kept → O(1) extra space, satisfying the problem’s constraint.