Eliminate entire blocks of possibilities at once by converging from both ends.
Finding a pair of numbers that add up to a target usually requires checking every possible pair (a double loop, taking O(n²) time). However, if the data is sorted, we can place a pointer at the start and a pointer at the end.
If their sum is too big, the largest number is to blame, so we move the right pointer left. If the sum is too small, the smallest number is to blame, so we move the left pointer right. Every step eliminates a number and all its remaining possible pairings instantly, letting us find the answer in just O(n) time.
This pattern requires the array to be sorted. It converges inwards, doing exactly one comparison per step.
def twoSum(nums, target):
left = 0
right = len(nums) - 1
while left < right:
curr = nums[left] + nums[right]
if curr == target:
return [left, right]
elif curr < target:
left += 1 # Too small, need a bigger number
else:
right -= 1 # Too big, need a smaller number
return [-1, -1]
We only traverse the array once from the outside in. No extra memory is allocated.
left < right. Do not use left <= right, because you cannot pair an element with itself.