[LeetCode] 1679. Max Number of K-Sum Pairs
You are given an integer array nums
and an integer k
.
In one operation, you can pick two numbers from the array whose sum equals k
and remove them from the array.
Return the maximum number of operations you can perform on the array.
Example 1:
Input: nums = [1,2,3,4], k = 5 Output: 2 Explanation: Starting with nums = [1,2,3,4]: - Remove numbers 1 and 4, then nums = [2,3] - Remove numbers 2 and 3, then nums = [] There are no more pairs that sum up to 5, hence a total of 2 operations.
Example 2:
Input: nums = [3,1,3,4,3], k = 6 Output: 1 Explanation: Starting with nums = [3,1,3,4,3]: - Remove the first two 3's, then nums = [1,4,3] There are no more pairs that sum up to 6, hence a total of 1 operation.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 109
1 <= k <= 109
K 和数对的最大数目。
给你一个整数数组 nums 和一个整数 k 。
每一步操作中,你需要从数组中选出和为 k 的两个整数,并将它们移出数组。
返回你可以对数组执行的最大操作数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/max-number-of-k-sum-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题的思路类似 two sum,我们需要创建一个 hashmap 来记录 input 中的数字,以便找到 k - nums[i]。这里我提供三种实现方式。
扫描一次
扫描一次的做法巧妙的地方在于他对当 nums[i] 正好是 K 的一半的 case 的处理。当 nums[i] 正好是K的一半的时候,此时 res 只 + 1,这样就能跟其他情况 merge 在一起而无需扫描两遍了。
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int maxOperations(int[] nums, int k) { 3 int res = 0; 4 HashMap<Integer, Integer> map = new HashMap<>(); 5 for (int num : nums) { 6 if (map.getOrDefault(k - num, 0) > 0) { 7 map.put(k - num, map.get(k - num) - 1); 8 res++; 9 } else { 10 map.put(num, map.getOrDefault(num, 0) + 1); 11 } 12 } 13 return res; 14 } 15 }
扫描两次
时间O(n)
空间O(n)
Java实现
1 class Solution { 2 public int maxOperations(int[] nums, int k) { 3 HashMap<Integer, Integer> map = new HashMap<>(); 4 for (int num : nums) { 5 map.put(num, map.getOrDefault(num, 0) + 1); 6 } 7 8 int res = 0; 9 for (int num : map.keySet()) { 10 int comp = k - num; 11 if (num == comp) { 12 res += map.get(num) / 2; 13 } else if (map.containsKey(comp)) { 14 int min = Math.min(map.get(num), map.get(comp)); 15 res += min; 16 map.put(num, map.get(num) - min); 17 map.put(comp, map.get(comp) - min); 18 } 19 } 20 return res; 21 } 22 }
排序 + 双指针逼近
因为题目只说每次操作需要找一对数字满足 a + b = k,不需要考虑重复元素,所以可以先对 input 数组排序,排序过后看两边指针指向的元素之和是否等于 k。
时间O(nlogn)
空间O(1)
Java实现
1 class Solution { 2 public int maxOperations(int[] nums, int k) { 3 Arrays.sort(nums); 4 int count = 0; 5 int left = 0; 6 int right = nums.length - 1; 7 while (left < right) { 8 int sum = nums[left] + nums[right]; 9 if (sum == k) { 10 count++; 11 left++; 12 right--; 13 } else if (sum > k) { 14 right--; 15 } else { 16 left++; 17 } 18 } 19 return count; 20 } 21 }