面试题9:数组配对

题目:给定N个整数,N为偶数,是否能找到N/2对,使得每队和都能被k整除。注意:每个元素只能出现在一个配对中。


观察:

     如果某个数能被k整除,那么该数除以k的余数为零。假设a和b之后能被k整除,即(a+b)%k=0,如果a%b=z,那么当z不等于0时,b%k=k-z;当z等于时,b%k=0。通过上面的推导,我们需要记录这个数组除以k之后的余数情况。然后从余数里找出配对。

    使用额外一个数组保存余数的情况,数组大小为k,A[i]记录余数为i的个数。有了这个余数个数的数组之后,我们需要考虑如下边界情况。

1)被k整除的个数是否为偶数?如果是奇数,那么就不可能找到N/2个能被k整除的数对(因为总会有至少一个余数不为0和余数为0的数对存在)

2)余数为i和余数k-i的个数是相同


代码实现:

package main
 
import (
    "fmt"
)
 
func checkPairable(nums []int, k int) bool {
    if k <= 0 {
        return false
    }
    // 该切片用来存储 数%k的余数的个数
    counts := make([]int, k)
    length := len(nums)
    for i := 0; i < length; i += 1 {
        counts[nums[i]%k] += 1
    }
    if counts[0]%2 != 0 {
        return false
    }
    for i := 1; i <= k/2; i += 1 {
        if counts[i] != counts[k-i] {
            return false
        }
    }
    return true
}
 
func main() {
    fmt.Println(checkPairable([]int{1, 2, 3, 4, 5, 6, 7, 8}, 3))
}
 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值