1099. Two Sum Less Than K π
Description
Given an array nums of integers and integer k, return the maximum sum such that there exists i < j with nums[i] + nums[j] = sum and sum < k. If no i, j exist satisfying this equation, return -1.
Example 1:
Input: nums = [34,23,1,24,75,33,54,8], k = 60 Output: 58 Explanation: We can use 34 and 24 to sum 58 which is less than 60.
Example 2:
Input: nums = [10,20,30], k = 15 Output: -1 Explanation: In this case it is not possible to get a pair sum less that 15.
Constraints:
1 <= nums.length <= 1001 <= nums[i] <= 10001 <= k <= 2000
Solutions
Solution 1: Sorting + Binary Search
Thinking
The largest pair sum strictly below \(k\) is quadratic if every pair is tested. After sorting, each \(x\) needs the largest right value below \(k-x\), which is a binary search.
For index \(i\), bisect_left on \((i,n)\) finds \(k-x\); the previous index, if still greater than \(i\), updates the answer.
The answer stays \(-1\) when no pair qualifies.
We can first sort the array \(nums\), and initialize the answer as \(-1\).
Next, we enumerate each element \(nums[i]\) in the array, and find the maximum \(nums[j]\) in the array that satisfies \(nums[j] + nums[i] < k\). Here, we can use binary search to speed up the search process. If we find such a \(nums[j]\), then we can update the answer, i.e., \(ans = \max(ans, nums[i] + nums[j])\).
After the enumeration ends, return the answer.
The time complexity is \(O(n \times \log n)\), and the space complexity is \(O(\log n)\). Here, \(n\) is the length of the array \(nums\).
1 2 3 4 5 6 7 8 9 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Solution 2: Sorting + Two Pointers
Thinking
One binary search per \(x\) is \(O(n\log n)\). Two pointers use the same monotonicity: a small sum moves the left end right; a sum of at least \(k\) moves the right end left.
A single pass covers the Pareto front of distinct-index pairs with a smaller constant.
Similar to Solution 1, we can first sort the array \(nums\), and initialize the answer as \(-1\).
Next, we use two pointers \(i\) and \(j\) to point to the left and right ends of the array, respectively. Each time we judge whether \(s = nums[i] + nums[j]\) is less than \(k\). If it is less than \(k\), then we can update the answer, i.e., \(ans = \max(ans, s)\), and move \(i\) one step to the right, otherwise move \(j\) one step to the left.
After the enumeration ends, return the answer.
The time complexity is \(O(n \times \log n)\), and the space complexity is \(O(\log n)\). Here, \(n\) is the length of the array \(nums\).
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |