「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
题目描述:
914. 卡牌分组 - 力扣(LeetCode) (leetcode-cn.com)
给定一副牌,每张牌上都写着一个整数。
此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组:
每组都有 X 张牌。
组内所有的牌上都写着相同的整数。
仅当你可选的 X >= 2 时返回 true。
示例一
输入: deck = [1,2,3,4,4,3,2,1]
输出: true
解释: 可行的分组是 [1,1],[2,2],[3,3],[4,4]
示例二
输入: deck = [1,1,1,2,2,2,3,3]
输出: false
解释: 没有满足要求的分组。
提示:
1 <= deck.length <= 10^40 <= deck[i] < 10^4
思路分析
最大公约数
- 首先需要遍历数组统计出每个数字的出现的频率
- 再对这些频率求他们共同的最大公约数,即能整除的最大数,也就是能分组的最大值
- 最然根据题目要求将这个值与1对比
AC代码
class Solution {
fun hasGroupsSizeX(deck: IntArray): Boolean {
var counter = HashMap<Int,Int>()
deck.forEach{it ->
counter.put(it, (counter[it]?:0)+ 1)
}
var sets = counter.values.toSet()
return if(sets.size == 1){
sets.elementAt(0) > 1
}else{
var isEven = true
sets.toList().let{
var gcd = it[0]
for( i in 1 until it.size){
gcd = gcd(gcd, it[i])
if(gcd <= 1){
return false
}
}
}
true
}
}
fun gcd(a:Int, b:Int):Int{
if(a < b){
return gcd(b, a)
}
return if(b == 0){
a
}else{
gcd(b, a % b)
}
}
}
总结
虽然是简单题,但是gcd是我们需要知道的知识点。
辗转相除,也就是那个gcd方法,用来求两个数的最大公约数, 欧几里得算法
参考
914. 卡牌分组 题解 - 力扣(LeetCode) (leetcode-cn.com)
辗转相除GCD,求所有数字的出现次数的最大公约数 - 卡牌分组 - 力扣(LeetCode) (leetcode-cn.com)
图解素数筛 C++ ( 不用GCD的暴力枚举~ - 卡牌分组 - 力扣(LeetCode) (leetcode-cn.com)
遍历计数数组并求出最大公约数(Java) - 卡牌分组 - 力扣(LeetCode) (leetcode-cn.com)