news 2026/4/15 7:21:34

算法题 卡牌分组

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法题 卡牌分组

914. 卡牌分组

问题描述

给定一副卡牌,每张卡牌上有一个整数。你需要判断是否可以将这些卡牌分成若干组,使得:

  • 每组至少有2张卡牌
  • 每组中的所有卡牌上的数字都相同

示例

输入: 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 解释: 没有办法将卡牌分成满足要求的组。 输入: deck = [1] 输出: false 解释: 卡牌数量少于2,无法分组。

算法思路

最大公约数

  1. 统计每个数字出现的频次
  2. 所有频次的最大公约数必须大于等于2
  3. 如果最大公约数 ≥ 2,说明可以将所有频次都分成大小为最大公约数的组

代码实现

方法一:最大公约数 + HashMap

classSolution{/** * 判断卡牌是否可以按要求分组 * * @param deck 卡牌数组,每个元素表示卡牌上的数字 * @return 如果可以分组返回true,否则返回false */publicbooleanhasGroupsSizeX(int[]deck){// 边界情况:卡牌数量少于2if(deck.length<2){returnfalse;}// 统计每个数字的出现频次Map<Integer,Integer>countMap=newHashMap<>();for(intcard:deck){countMap.put(card,countMap.getOrDefault(card,0)+1);}// 获取所有频次值intgcdValue=-1;for(intcount:countMap.values()){if(gcdValue==-1){gcdValue=count;}else{gcdValue=gcd(gcdValue,count);// 如果最大公约数已经变成1,可以提前返回if(gcdValue==1){returnfalse;}}}// 所有频次的最大公约数必须大于等于2returngcdValue>=2;}/** * 计算两个数的最大公约数(欧几里得算法) * * @param a 第一个数 * @param b 第二个数 * @return 最大公约数 */privateintgcd(inta,intb){while(b!=0){inttemp=b;b=a%b;a=temp;}returna;}}

方法二:Stream API

classSolution{/** * 使用Java 8 Stream API * * @param deck 卡牌数组 * @return 如果可以分组返回true,否则返回false */publicbooleanhasGroupsSizeX(int[]deck){if(deck.length<2){returnfalse;}// 统计频次并计算GCDMap<Integer,Long>countMap=Arrays.stream(deck).boxed().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));longgcdValue=countMap.values().stream().reduce(-1L,(a,b)->a==-1?b:gcd(a,b));returngcdValue>=2;}privatelonggcd(longa,longb){while(b!=0){longtemp=b;b=a%b;a=temp;}returna;}}

算法分析

  • 时间复杂度:O(n + m log k)
    • n 是卡牌总数
    • m 是不同数字的个数
    • k 是最大频次值
    • 最大公约数计算的时间复杂度为 O(log k)
  • 空间复杂度
    • 方法一:O(m),m为不同数字的个数
    • 方法二:O(maxCard),maxCard为卡牌上的最大数字

算法过程

输入:deck = [1,2,3,4,4,3,2,1]

  1. 统计频次:{1:2, 2:2, 3:2, 4:2}
  2. 计算最大公约数:
    • 初始gcdValue = 2
    • gcd(2, 2) = 2
    • gcd(2, 2) = 2
    • gcd(2, 2) = 2
  3. 最终gcdValue = 2 >= 2,返回true

输入:deck = [1,1,1,2,2,2,3,3]

  1. 统计频次:{1:3, 2:3, 3:2}
  2. 计算最大公约数:
    • 初始gcdValue = 3
    • gcd(3, 3) = 3
    • gcd(3, 2) = 1
  3. 最终gcdValue = 1 < 2,返回false

测试用例

publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 测试用例1:标准示例int[]deck1={1,2,3,4,4,3,2,1};System.out.println("Test 1: "+solution.hasGroupsSizeX(deck1));// true// 测试用例2:无法分组int[]deck2={1,1,1,2,2,2,3,3};System.out.println("Test 2: "+solution.hasGroupsSizeX(deck2));// false// 测试用例3:单张卡牌int[]deck3={1};System.out.println("Test 3: "+solution.hasGroupsSizeX(deck3));// false// 测试用例4:两张相同卡牌int[]deck4={1,1};System.out.println("Test 4: "+solution.hasGroupsSizeX(deck4));// true// 测试用例5:所有卡牌相同int[]deck5={1,1,1,1,1,1};System.out.println("Test 5: "+solution.hasGroupsSizeX(deck5));// true// 测试用例6:频次互质int[]deck6={1,1,2,2,2,2};System.out.println("Test 6: "+solution.hasGroupsSizeX(deck6));// true// 测试用例7:频次为质数int[]deck7={1,1,1,1,2,2,2,2,2,2};System.out.println("Test 7: "+solution.hasGroupsSizeX(deck7));// true// 测试用例8:包含0int[]deck8={0,0,1,1,1,1,2,2,2,2,2,2};System.out.println("Test 8: "+solution.hasGroupsSizeX(deck8));// true// 测试用例9:大数值int[]deck9={1000,1000,1000,1000,1000,1000};System.out.println("Test 9: "+solution.hasGroupsSizeX(deck9));// true}

关键点

  1. 最大公约数

    • 所有频次必须有一个公共因子 ≥ 2
    • 这个公共因子就是所有频次的最大公约数
  2. 边界处理

    • 卡牌总数 < 2 时直接返回 false

常见问题

  1. 为什么最大公约数 ≥ 2 ?
    • 如果最大公约数 = g ≥ 2,那么每个频次都可以被g整除
    • 每个数字可以分成count/g组,每组g张卡牌
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 18:24:53

对比实测:传统VS快马AI安装JAVA,效率提升800%

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建JAVA安装效率对比测试套件&#xff1a;1. 设计三种安装方式测试用例 2. 自动记录各阶段耗时 3. 捕获配置错误类型 4. 生成可视化对比图表 5. 输出优化建议报告。重点分析AI自动…

作者头像 李华
网站建设 2026/4/9 17:07:27

企业级SQL注入防御实战:从SQLI-LABS到真实场景

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个企业级SQL注入防御演示系统&#xff0c;包含&#xff1a;1. 模拟电商网站&#xff08;含用户登录、商品搜索、订单管理&#xff09;2. 集成SQLI-LABS中的典型漏洞模式 3. …

作者头像 李华
网站建设 2026/4/10 19:50:23

ResNet18优化指南:推理速度提升3倍的参数设置

ResNet18优化指南&#xff1a;推理速度提升3倍的参数设置 1. 背景与挑战&#xff1a;通用物体识别中的效率瓶颈 在当前AI应用广泛落地的背景下&#xff0c;通用物体识别已成为智能监控、内容审核、辅助驾驶等场景的基础能力。其中&#xff0c;ResNet-18作为轻量级深度残差网络…

作者头像 李华
网站建设 2026/4/5 22:15:59

AI万能分类器使用案例:智能推荐系统构建

AI万能分类器使用案例&#xff1a;智能推荐系统构建 1. 引言&#xff1a;AI万能分类器的现实价值 在当今信息爆炸的时代&#xff0c;如何从海量非结构化文本中快速提取语义、实现自动化归类&#xff0c;已成为智能系统的核心能力之一。传统文本分类方法依赖大量标注数据和模型…

作者头像 李华
网站建设 2026/4/8 15:52:13

Python条件判断的5个真实业务场景应用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个电商促销规则引擎&#xff1a;1. 根据用户会员等级(普通/VIP/SVIP)应用不同折扣 2. 购物满300减50 3. 特定商品组合购买额外优惠 4. 使用清晰的if-elif-else结构实现 5. 输…

作者头像 李华
网站建设 2026/3/31 3:30:16

1小时快速开发局域网传输工具原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速开发一个局域网传输工具的概念验证原型。功能包括&#xff1a;1. 最基本的文件传输功能&#xff1b;2. 极简命令行界面&#xff1b;3. 支持同一网络下的设备发现&#xff1b;4…

作者头像 李华