We have a sorted array and need to find two numbers that add up to a given target. Three constraints shape the approach: the array is sorted, we must return 1-indexed positions, and we can only use constant extra space.
The constant-space requirement is what separates this problem from the original Two Sum. It rules out the hash map approach, which would store seen values as it scans. We have to find the pair using the structure of the array itself instead of an auxiliary data structure.
The sorted order gives us that structure. Because the array is sorted, the position of an element tells us how its value compares to everything around it, and we can use that to decide where the matching pair must lie.
numbers.length up to 3 * 10^4 → an O(n^2) brute force runs about 4.5 * 10^8 pair checks in the worst case, slow enough that we should aim for O(n log n) or O(n).Try every pair of elements and check if it adds up to the target. For each element at index i, check every element at index j > i. If their sum equals the target, return the 1-indexed positions.
This ignores the sorted property entirely, so it leaves a lot of performance on the table. It works as a correctness baseline before we optimize.
i from 0 to n-2.i, loop through each index j from i+1 to n-1.numbers[i] + numbers[j] equals the target, return [i+1, j+1].The brute force scans linearly for each element's complement. Because the array is sorted, the next approach replaces that linear scan with a binary search.
Fix one element and search for its complement. For each numbers[i], the value we need is complement = target - numbers[i]. Since the array is sorted, a binary search on the portion after index i finds that complement in O(log n) instead of the O(n) linear scan.
We search only the subarray to the right of i (indices i+1 onward). This avoids pairing an element with itself and avoids re-checking pairs we already tested when i was smaller.
i from 0 to n-2:complement = target - numbers[i].complement in the subarray from index i+1 to n-1.j, return [i+1, j+1].Binary search cut the inner loop from O(n) to O(log n), but each element is still searched independently, repeating work. The next approach scans the array once with two pointers that move toward each other, reaching O(n).
Place one pointer at the beginning (smallest element) and one at the end (largest element). Their sum tells us which way to move.
Each move discards one element, and because the array is sorted, the discarded element can never be part of the answer with any remaining element. The window between the two pointers shrinks by one each step, so the scan ends in a single pass.
The reason a discarded element is safe to drop: suppose numbers[left] + numbers[right] < target. Every element from left+1 to right is at most numbers[right] (the array is sorted), so pairing numbers[left] with any of them gives a sum at most numbers[left] + numbers[right], which is still below the target. No pair involving numbers[left] can reach the target, so removing left loses no valid answer. The symmetric argument holds when the sum exceeds the target and we drop right. Since exactly one solution exists, the pointers cannot pass it, and they meet at it before crossing.
left = 0 and right = n - 1.left < right:sum = numbers[left] + numbers[right].sum == target, return [left + 1, right + 1].sum < target, increment left (we need a larger sum).sum > target, decrement right (we need a smaller sum).