卡牌分组

  • https://leetcode.cn/problems/x-of-a-kind-in-a-deck-of-cards/

描述

  • 给定一副牌,每张牌上都写着一个整数。

  • 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组:

    • 每组都有 X 张牌。
    • 组内所有的牌上都写着相同的整数。
  • 仅当你可选的 X >= 2 时返回 true。

示例 1:

输入:deck = [1,2,3,4,4,3,2,1]
输出:true
解释:可行的分组是 [1,1],[2,2],[3,3],[4,4]

示例 2:

输入:deck = [1,1,1,2,2,2,3,3]
输出:false
解释:没有满足要求的分组。

提示:

  • 1 <= deck.length <= 1 0 4 10^4 104
  • 0 <= deck[i] < 1 0 4 10^4 104

算法实现

1 )方案 1

function hasGroupsSizeX(deck: number[]): boolean {// 边界情况if (deck.length < 2) return false// 对牌进行排序,无所谓顺序deck.sort()let flag: boolean = true // 最终的返回结果let arr: number[][] = []for (let i = 0, len = deck.length, tmp = []; i < len; i ++) {tmp.push(deck[i])// 基于当前的i逐个对比,判断是否和arr[i] 相同, 注意这个边界值for (let j = i + 1; j <= len; j ++) {// 相同时,逐一加入tmp进行存储if (deck[i] === deck[j]) {tmp.push(deck[i])} else {// 不相同时// 数组长度不满足2的边界值处理if (tmp.length < 2) {return false}arr.push([].concat(tmp)) // 注意:这里数组是一个新的对象会被push到result中, 不能直接用tmp这个引用对象tmp.length = 0 // 清空临时数组i = j - 1 // 将i的下标移动到 j-1break // 跳出此层循环}}if (!flag) {break}}let result: number[] = arr.map(item => item.length) // 二维数据编程存储长度的一维数组result = [...new Set(result)]  // 对数组去重,减少重复运算// 求是否是最大公约数函数const isGcd = (arr: number[]) => {// 所有的数组都是一个长度if (arr.length === 1) {return true}const gcd = (x: number,y: number) => !(x % y) ? y : gcd(y, x % y) // 求两个数的最大公约数let final = 1 // 初始化最大公约数为1while (arr.length > 1) {let num1 = arr[0], num2 = arr[1];final = gcd(num1, num2)if(final === 1) {return false} else {arr.splice(0,2, final) // // 迭代,继续求最大公约数}}return final !== 1}return isGcd(result)
}
  • 上述写法很长,基于正常的思维来处理的,两层循环进行聚类分组
  • 之后简化数组存储,从存储原数据变更为存储同一数值类型的卡牌长度
  • 然后,对所有数组进行去重操作,留下一个唯一的数组
  • 在这个唯一数组中求最大公约数,如果最大公约数为1,则返回false, 否则返回true
  • 需要注意的是:一些边界值的处理,有些情况开启边界值检测可以提前结束程序
  • 这个程序的缺点是:复杂,维护性不佳

2 )方案 2

function hasGroupsSizeX(deck: number[]): boolean {// 边界判断if (deck.length < 2) return false// 存储每张卡牌的总数let result: number[] = []// 临时存储对象const tmp: object = {}// 使用对象来存储累加当前数据的值deck.forEach(item => {tmp[item] = tmp[item] ? tmp[item] + 1 : 1})// 将最终的结果存放到一个数组中for (let v of Object.values(tmp)) {result.push(v)}// 对数组进行去重result = [... new Set(result)]// 求两个数的最大公约数const gcd = (x: number,y: number) => !(x % y) ? y : gcd(y, x % y)while (result.length > 1) {const a = result.shift() // 移除当前数组第一个 并把返回值赋给 aconst b = result.shift() // 移除当前数组第一个 并把返回值赋给 b// 得到当前最大公约数const v = gcd(a, b)if (v === 1) {return false} else {result.unshift(v) // 将当前得到的新约数存入数组开头,进入下一个循环}}return result.length ? result[0] > 1 : false
};
  • 上述程序,通过修改数据结构,将处理数据的复杂度大大降低
  • 注意下,上述记录同一数值的卡牌数量的object和while循环处理的精妙之处

数据结构与算法之数组: Leetcode 914. 卡牌分组 (Typescript版)相关推荐

  1. LeetCode 914. 卡牌分组

    914. 卡牌分组 思路:统计个数,然后求最小公约数 class Solution { public:bool hasGroupsSizeX(vector<int>& deck) ...

  2. python【力扣LeetCode算法题库】914. 卡牌分组(reduce collections.Counter)

    给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的整数. 仅当你可选的 X > ...

  3. LeetCode 914. 卡牌分组(最大公约数)

    1. 题目 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的整数. 仅当你可选的 ...

  4. 2021-12-8 Leetcode 914.卡牌分组

    class Solution {public:bool hasGroupsSizeX(vector<int>& deck) {map<int,int> hash_map ...

  5. Leetcode每日一题(914. 卡牌分组)

    914. 卡牌分组 题目: 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的整数 ...

  6. js + leetcode刷题:No.914 卡牌分组

    思路:计数:求最大公约数,与2比较 题目: 卡牌分组 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内 ...

  7. 力扣:914. 卡牌分组 题解(Java)

    题目地址:卡牌分组 题目描述: 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的 ...

  8. 【Leetcode】914. 卡牌分组

    文章目录 [题目] [题目分析] [代码实践] [题目] 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌. 组内所有的牌上都写着相同的整数. 仅当 ...

  9. 力扣914.卡牌分组

    题目描述 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组: 每组都有 X 张牌.组内所有的牌上都写着相同的整数. 仅当你可选的 X ...

最新文章

  1. 找不到jar包的解决方法
  2. 23种设计模式C++源码与UML实现--原型模式
  3. Js 变量声明提升和函数声明提升
  4. 【Python面试】 说说Python中有几种数据类型?​
  5. IOS之Label画一条删除线
  6. Thinkpad X240使用U盘安装Win7系统
  7. 桶分类 算法_桶分类算法
  8. Android实现按钮点击效果(第一次点击变色,第二次恢复)
  9. AC日记——单词倒排 1.7 28
  10. 卷积码编码和译码c语言,卷积码编码和译码.doc
  11. android 人脸 动画表情包,巧笑表情包怎么制作 Android好玩的emoji人脸表情软件推荐...
  12. Adobe Premiere基础-声音调整(音量矫正,降噪,电话音,音高换挡器,参数均衡器)(十八)
  13. 小米手机自带计算机不能用怎么解决,如果小米手机无法进入系统怎么办?
  14. 相位误差对SAR图像的影响
  15. BigBlueButton 2.2安装指南
  16. 富贵竹叶子发黄怎么办?
  17. Deep Mind 团队论文Playing Atari with Deep Reinforcement Learning复现
  18. 贝壳CVR转化率预估模型实践
  19. 人工智能导论(2)——启发式算法(八数码问题)
  20. python:数据可视化 相关系数热力图绘制

热门文章

  1. Lua脚本快速上手(附示例程序代码)
  2. oracle存储过程显示弹框,oracle存储过程异常信息的显示
  3. linux下cp -pf,Linux下cp直接覆盖
  4. 面试资料-JAVA基础知识
  5. 杂乱身份证整理之终极大法
  6. 在OpenCV里用arrowedLine画箭头图形
  7. Tableau desktop(二)--数据连接及数据字段
  8. 高数【积分-不定积分】--猴博士爱讲课
  9. 离职了,写点什么吧~
  10. 江南大学计算机考研好毕业吗,江南大学考研难吗?一般要什么水平才可以进入?...