LeetCode.914 卡牌分组

207 阅读1分钟

「这是我参与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^4
  • 0 <= deck[i] < 10^4

思路分析

最大公约数

  1. 首先需要遍历数组统计出每个数字的出现的频率
  2. 再对这些频率求他们共同的最大公约数,即能整除的最大数,也就是能分组的最大值
  3. 最然根据题目要求将这个值与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)