You are given an array of integers nums
and an integer k
. Your task is to find the maximum sum of two distinct numbers in the nums
array that is strictly less than k
. If no such pair exists, return -1.
For example:
nums = [1, 3, 5, 7], k = 8
. The maximum sum less than 8 is 1 + 5 = 6
. Therefore, the output should be 6.nums = [5, 20, 110, 10, 15], k = 40
. The possible sums less than 40 are 5+20
, 5+10
, 5+15
, 20+10
, 20+15
, and 10+15
. The largest of these is 20 + 15 = 35
. Therefore, the output should be 35.nums = [1, 2, 3], k = 1
. Since no two numbers in the array sum to a value less than 1, the function should return -1.Describe an algorithm to solve this problem efficiently. What is the time and space complexity of your solution? Consider edge cases such as an empty input array or when no pairs sum to less than k
.
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. We will look at each combination to see if it meets our condition. We aim to find the largest sum of two numbers that is still smaller than the specified limit.
Here's how the algorithm would work step-by-step:
def two_sum_less_than_k_brute_force(numbers, limit):
largest_sum_smaller_than_limit = -1
# Iterate through each number in the list
for first_number_index in range(len(numbers)):
# For each number, iterate through the rest of the numbers
for second_number_index in range(first_number_index + 1, len(numbers)):
current_sum = numbers[first_number_index] + numbers[second_number_index]
# Check if the current sum is less than the limit
if current_sum < limit:
# Keep track of the largest sum that satisfies this condition
largest_sum_smaller_than_limit = max(largest_sum_smaller_than_limit, current_sum)
return largest_sum_smaller_than_limit
The best way to solve this problem is to first organize the numbers in ascending order. Then, use two pointers, one starting at the beginning and the other at the end, to efficiently find the pair that adds up to the largest sum less than the target value.
Here's how the algorithm would work step-by-step:
def two_sum_less_than_k(numbers, target):
numbers.sort()
left_pointer = 0
right_pointer = len(numbers) - 1
max_sum_less_than_target = -1
while left_pointer < right_pointer:
current_sum = numbers[left_pointer] + numbers[right_pointer]
# Update the result if current sum is less than target.
if current_sum < target:
max_sum_less_than_target = max(max_sum_less_than_target, current_sum)
# Try to find a larger sum.
left_pointer += 1
# We need a smaller sum.
else:
right_pointer -= 1
return max_sum_less_than_target
Case | How to Handle |
---|---|
Null or empty input array | Return 0 immediately, as no sum less than K is possible. |
Input array with fewer than 2 elements | Return 0, as no pair can be formed. |
All numbers in the array are greater than or equal to K | Return 0, as no sum less than K is possible. |
Array contains only one unique number repeated multiple times | Ensure that the algorithm does not add the number to itself, unless K is greater than twice the number. |
Large input array (scalability considerations) | Sorting the array upfront allows for a two-pointer approach with O(n log n) time complexity, avoiding quadratic complexity of naive solutions. |
Negative numbers in the input array | The algorithm should correctly handle negative numbers and consider their contribution to the sum. |
K is a very small negative number | The solution should correctly identify the largest possible sum less than a negative K, potentially being a large negative number itself. |
Duplicate pairs exist | The two-pointer approach implicitly handles duplicate pairs by moving pointers and ensuring the calculated sum is the largest possible sum less than K. |