题目描述
[1679] K 和数对的最大数目
给你一个整数数组 nums 和一个整数 k 。
每一步操作中,你需要从数组中选出和为 k 的两个整数,并将它们移出数组。
返回你可以对数组执行的最大操作数。
示例 1:
输入:nums = [1,2,3,4], k = 5
输出:2
解释:开始时 nums = [1,2,3,4]:
- 移出 1 和 4 ,之后 nums = [2,3]
- 移出 2 和 3 ,之后 nums = []
不再有和为 5 的数对,因此最多执行 2 次操作。
示例 2:
输入:nums = [3,1,3,4,3], k = 6
输出:1
解释:开始时 nums = [3,1,3,4,3]:
- 移出前两个 3 ,之后nums = [1,4,3]
不再有和为 6 的数对,因此最多执行 1 次操作。
提示:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
1 <= k <= 10^9
Related Topics
- 数组
- 哈希
- 双指针
题目剖析&信息挖掘
题目是要找到和为k的数对,可以用哈希法和双指针法解决
解题思路
根据题意一个数字用完后会删除,所以一个数字最多只用一次。利用贪心原理,去遍历数组,找到另一个数字并从中删除。这就转化成从数组中找出和为k的对数。和之前的两数之和、三数之和、四数之和的题类似。有2种做法一种是直接哈希法,另一种是排序以后用双指针法。
方法一 哈希法
思路
- 维护哈希表存储数字的个数
- 遍历数组,对于遍历的数字n,查看前面有没与之加和为k的数
- 如果有就删除k-n,并sum++,如果没有就把n加入到哈希表中。
func maxOperations(nums []int, k int) int {
m:= make(map[int]int, len(nums)) //
sum := 0
for _, n:= range nums {
if m[n]>0 {
sum++
m[n]--
} else {
m[k-n]++ // 这里存储的相减后的结果
}
}
return sum
}
注意
- 哈希设计要用统计,不能用bool
- 同种组合有多组的情况, 如[3,3,3,3] , 6
知识点
- 数组
- 哈希
复杂度
- 时间复杂度:O(n)
- 空间复杂度:O(n)
代码实现
func maxOperations(nums []int, k int) int {
m:= make(map[int]int, len(nums)) //
sum := 0
for _, n:= range nums {
if m[n]>0 {
sum++
m[n]--
} else {
m[k-n]++ // 这里存储的相减后的结果
}
}
return sum
}
方法二 双指针法
思路
- 先对数组排序
- 用双指针对头尾进行遍历
func maxOperations(nums []int, k int) int {
sort.Sort(nums)
sum := 0
left, right := 0, len(nums)-1
// nums[left]<nums[right]
for ;left<right; {
if nums[left]+nums[right] == k {
sum++
left++
right--
} else if nums[left]+nums[right] < k { // 说明小的数字要增大
left++
} else { // 大的数字要减少
right--
}
}
return sum
}
注意
- 一定要先排序
- 同种组合有多组的情况, 如[3,3,3,3] , 6
知识点
- 数组
- 双指针
- 排序
复杂度
- 时间复杂度:O(nlog(n))
- 空间复杂度:O(n)
参考
代码实现
func maxOperations(nums []int, k int) int {
sort.Sort(sort.IntSlice(nums))
sum := 0
left, right := 0, len(nums)-1
// nums[left]<nums[right] 恒成立
for ;left<right; {
if nums[left]+nums[right] == k {
sum++
left++
right--
} else if nums[left]+nums[right] < k { // 说明小的数字要增大才有可能使和=k
left++
} else { // 大的数字要减少,同理。
right--
}
}
return sum
}
相关题目
https://leetcode-cn.com/problems/two-sum/
https://leetcode-cn.com/problems/3sum/
https://leetcode-cn.com/problems/4sum/