1. 问题描述:
给你一个整数数组 arr 和一个整数 k ,其中数组长度是偶数,值为 n 。现在需要把数组恰好分成 n / 2 对,以使每对数字的和都能够被 k 整除。如果存在这样的分法,请返回 True ;否则,返回 False 。
示例 1:
输入:arr = [1,2,3,4,5,10,6,7,8,9], k = 5
输出:true
解释:划分后的数字对为 (1,9),(2,8),(3,7),(4,6) 以及 (5,10) 。
示例 2:
输入:arr = [1,2,3,4,5,6], k = 7
输出:true
解释:划分后的数字对为 (1,6),(2,5) 以及 (3,4) 。
示例 3:
输入:arr = [1,2,3,4,5,6], k = 10
输出:false
解释:无法在将数组中的数字分为三对的同时满足每对数字和能够被 10 整除的条件。
示例 4:
输入:arr = [-10,10], k = 2
输出:true
示例 5:
输入:arr = [-1,1,-2,2,-3,3,-4,4], k = 3
输出:true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-array-pairs-are-divisible-by-k
2. 思路分析:
① 分析题目可以知道最容易想到的是将arr数组中的数字对k进行取余,然后对k取余之后的数字进行计数,记录他们出现的次数(对余数进行分组),可以使用哈希表(字典)对取余之后的数字进行计数,因为使用的是python语言所以使用字典对arr[i] % k取余之后的结果进行计数,这样我们就可以遍历字典中记录的arr[i] % k的余数key以及对应的次数value,检查k - key是否存在于字典中,只有当字典中存在k - key表示可以找到另外一组余数为k - key使得相加的结果能够被k整除,所以当k - key不在字典中或者是当前余数key与另外相加等于k的余数k - key出现的次数不相等的时候这种情况是不能够对所有的数字分为两组使得每一组都能够被k整除,比如出现了余数为1的为3次,余数为4的不存在或者是余数为4的不等于3次说明都是不符合题目条件的,这个时候返回False(取余之后相加的结果等于k那么取余之前相加的结果肯定能够被k整除)
② 并且还需要考虑余数等于0的情况,因为我们判断是k - key是否存在于字典中,而余数等于0是找不到余数等于k的情况使得相加能够被k整除的,而且只要是余数等于0那么两者就可以组成一组使得两者相加的结果能够被k整除,所以这个时候我们需要对这种情况进行额外判断,在循环中可以判断余数大于0的情况循环结束之后就可以判断余数等于0的情况是否是偶数(偶数才能够进行一一分组)即可
3. 代码如下:
import collections
from typing import List
class Solution:
def canArrange(self, arr: List[int], k: int) -> bool:
dic = collections.Counter(arr[i] % k for i in range(len(arr)))
for key, value in dic.items():
if key > 0 and dic[k - key] != value: return False
# 对余数等于0的情况判断是否是偶数
return dic[0] % 2 == 0
import collections
from typing import List
class Solution:
def canArrange(self, arr: List[int], k: int) -> bool:
dic = collections.defaultdict(int)
for i in range(len(arr)):
dic[arr[i] % k] += 1
for key, value in dic.items():
# 对于余数为0的情况要特别考虑
if key > 0 and (k - key not in dic or dic[k - key] != value):
return False
# 判断余数为0的是否全部可以组成一组
return dic[0] % 2 == 0