Given a 1-indexed array of integers numbers
that is already sorted in non-decreasing order, find two numbers such that they add up to a specific target
number. Let these two numbers be numbers[index1]
and numbers[index2]
where 1 <= index1 < index2 <= numbers.length
.
Return the indices of the two numbers, index1
and index2
, added by one as an integer array [index1, index2]
of length 2.
The tests are generated such that there is exactly one solution. You may not use the same element twice.
Your solution must use only constant extra space.
Example 1:
Input: numbers = [2,7,11,15], target = 9 Output: [1,2] Explanation: The sum of 2 and 7 is 9. Therefore, index1 = 1, index2 = 2. We return [1, 2].
Example 2:
Input: numbers = [2,3,4], target = 6 Output: [1,3] Explanation: The sum of 2 and 4 is 6. Therefore index1 = 1, index2 = 3. We return [1, 3].
Example 3:
Input: numbers = [-1,0], target = -1 Output: [1,2] Explanation: The sum of -1 and 0 is -1. Therefore index1 = 1, index2 = 2. We return [1, 2].
Constraints:
2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers
is sorted in non-decreasing order.-1000 <= target <= 1000
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to this problem is like trying every possible pair of numbers to see if they add up to the target. It is a very direct, but potentially slow, way to find the solution. We simply check every combination until we find the right one.
Here's how the algorithm would work step-by-step:
def two_sum_brute_force(numbers, target):
# Iterate through each number in the list.
for first_index in range(len(numbers)):
# For each number, iterate through all subsequent numbers.
for second_index in range(first_index + 1, len(numbers)):
# Check if the sum of current pair equals the target.
if numbers[first_index] + numbers[second_index] == target:
return [first_index + 1, second_index + 1]
# Return an empty list to indicate no solution was found.
return []
Since the numbers are already sorted, we can use this ordering to our advantage. We'll start by looking at the numbers at the beginning and the end and then carefully move inwards until we find the pair that adds up to our target.
Here's how the algorithm would work step-by-step:
def find_two_sum(numbers, target):
left_index = 0
right_index = len(numbers) - 1
while left_index < right_index:
current_sum = numbers[left_index] + numbers[right_index]
if current_sum == target:
return [left_index + 1, right_index + 1]
elif current_sum < target:
# Sum is too small, need larger numbers
left_index += 1
else:
# Sum is too large, need smaller numbers
right_index -= 1
# No such pair exists
return []
Case | How to Handle |
---|---|
Empty input array | Return an empty array or null to indicate no solution when the input array is empty. |
Input array with fewer than 2 elements | Return an empty array or null since a pair cannot be formed with less than two numbers. |
No solution exists (no two numbers sum to the target) | Return an empty array or null to signal that no such pair exists in the input. |
Large input array that could cause performance issues | Two-pointer approach offers O(n) time complexity, ensuring good performance for large inputs. |
Input array contains duplicate numbers and a valid solution exists using duplicates | The two-pointer approach will correctly identify the indices of the duplicate numbers that sum to the target. |
Input array contains negative numbers | The two-pointer approach works correctly with negative numbers since the array is sorted. |
The target value is very large and might cause integer overflow during addition | Use a language construct to prevent integer overflow, like casting to a larger numeric type if necessary or checking before adding. |
Multiple valid solutions exist | Return the first valid solution encountered; the problem statement doesn't require finding all solutions. |