博客
关于我
1679 K 和数对的最大数目(使用字典对余数分组、排序 + 双指针)
阅读量:357 次
发布时间:2019-03-04

本文共 2085 字,大约阅读时间需要 6 分钟。

1. 问题描述:

给你一个整数数组 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

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/max-number-of-k-sum-pairs

2. 思路分析:

① 看到题目首先想到的是余数分组的概念,之前在力扣中有一道的题目与这道题目是很类似的,分析题目可以知道本质上都是余数分组,也就是需要计算nums[i] % k的各个余数出现的次数,这道题目限制了一个条件就是两个数字的和为k所以我们只需要对满足nums[i] < k的数字进行计数,这样遍历数组结束之后我们就可以得到数组中的数字对k取余的各个余数出现的次数(因为使用的是python语言所以使用字典对余数出现的次数进行计数),这样接下来就可以遍历字典,首先判断k - key是否存在(key为当前遍历的字典的键)如果存在说明两者的和肯定为k,所以我们取出两个余数出现的最小的次数即可(最小的次数表示两者进行匹配),并且我们知道在遍历字典的过程中余数的分组的数目计算了两次,所以最终的结果需要除以2,由于题目中规定nums[i] > 0,所以不需要考虑余数等于0的情况,最终返回除以2的结果即可

② 主要是需要弄清楚题目的本质:余数分组,那么剩下来的就比较简单了

③ 考虑到求解的是两个数字相加和为k的问题所以我们可以先对数组进行排序,这样就可以使用两个变量l,r模拟移动左边指针与右边指针的位置(排序 + 双指针),当nums[l] + nums[r] > k说明右边的指针需要向左移动,当nums[l] + nums[r]  < k的时候那么左边的指针需要向右移动,当相等的时候那么两个指针同时移动:左边指针往右移动,右边指针往左移动,并且计数加1,循环结束之后返回计数的结果即可

3. 代码如下:

余数分组:

import collectionsfrom typing import Listclass Solution:    def maxOperations(self, nums: List[int], k: int) -> int:        res = 0        dic = collections.defaultdict(int)        for i in range(len(nums)):            # 注意需要一个限制条件: 只有两个数字都是小于k相加才有可能等于k            if nums[i] < k:                dic[nums[i] % k] += 1        for key, value in dic.items():            if k - key in dic:                res += min(value, dic[k - key])        res //= 2        return res

排序 + 双指针:

import collectionsfrom typing import Listclass Solution:    def maxOperations(self, nums: List[int], k: int) -> int:        res = 0        # 使用sort函数排序那么可以修改原来的数组        nums.sort()        l, r = 0, len(nums) - 1        while l < r:            if nums[l] + nums[r] > k:                r -= 1            elif nums[l] + nums[r] < k:                l += 1            else:                l += 1                r -= 1                res += 1        return res

 

转载地址:http://kwwg.baihongyu.com/

你可能感兴趣的文章
OSI 7 层网络模型
查看>>
Spring Bean 生命周期
查看>>
JDK 内置线程池
查看>>
JVM 参数默认值查询
查看>>
异常的继承结构
查看>>
SVN 和 Git 区别
查看>>
JDK 内置的多线程协作工具类的使用场景
查看>>
Java 源代码到运行的过程
查看>>
Java 中哪些对象可以获取类对象
查看>>
linux 的 cp 命令如何复制不提示覆盖
查看>>
缓存穿透 / 缓存击穿 / 缓存雪崩 / 缓存一致性
查看>>
linux 的 sleep 命令
查看>>
js 的 let var const 区别
查看>>
vue计算属性和监听器区别
查看>>
前端常用知识随手记
查看>>
11.2.6 时间值的小数秒
查看>>
11.2.7 日期和时间类型之间的转换
查看>>
redis 内存溢出_从数据存储的角度告诉你Redis为什么这么快!
查看>>
实例分析Facebook激励视频广告接入
查看>>
实例:使用OKGO下载网络压缩包资源,然后解压缩放在本地使用
查看>>