当前位置: 首页 > news >正文

剑指offer-45、扑克牌顺⼦

题⽬描述

扑克牌可以组成顺⼦,⼤\⼩ 王可以看成任何数字,并且 A 看作 1 , J 为 11 , Q 为 12 , K 为 13 。 5张牌 【A,0,3,0,5】 就可以变成“ 1,2,3,4,5 ”(⼤⼩王分别看作 2 和 4 ),这样就组成了顺⼦。(可以认为⼤⼩王是 0 。)

输⼊五张牌,如果牌能组成顺⼦就输出true,否则就输出 false 。

示例1
输⼊:[0,3,2,6,4]
返回值:true

思路及解答

排序遍历

这是最直观的解法,通过排序后分析牌之间的间隔关系来判断。

排序后统计大小王数量,检查非王牌之间的间隔是否可用大小王填补:先排序,0肯定是靠左边,然后统计0的个数,后⾯的数,按照第⼀个⾮0的数进⾏递增,如果不是递增,则需要使⽤ 0 牌补充,如果 0 牌不够,需要放回 false ,否则直到遍历完数组,返回true 。

public boolean IsContinuous(int[] numbers) {// 数组⻓度不符合直接返回if (numbers == null || numbers.length < 5) {return false;}// 先排序Arrays.sort(numbers);// 统计0的个数int numOfZero = 0;// 初始化索引int start;// 统计0的个数for (start = 0; start < numbers.length; start++) {if (numbers[start] == 0) {numOfZero++;} else {// ⾮0的时候跳出break;}// 暂存0的个数int n = numOfZero;// 当前的数值int cur = numbers[numOfZero];// 从0的下两个位置开始for (start++; start < numbers.length;) {// 如果可变的牌数量为0if (numOfZero == 0) {// 和前⾯的⼀个对⽐if (numbers[start] != cur + 1) {// 不等于当前数值+1的话,直接返回falsereturn false;} else {// 当前数值+1cur++;}} else {// 不等于当前数值+1的话,直接返回falseif (numbers[start] != cur + 1) {// 可变牌数量-1numOfZero--;//当前值+1cur++;// 遍历下⼀张牌continue;} else {// 相等则直接将当前值+1cur++;}}// 索引滑动到下⼀张牌start++;}return true;}
}
  • 时间复杂度:O(n log n),主要来自排序操作
  • 空间复杂度:O(1),只使用常数级别额外空间

哈希集合法(推荐)

利用HashSet实现去重,同时记录最大值和最小值。

初始化⼀个最⼩牌 14 ,最⼤牌 0 ,直接使⽤ set 保存数组的元素,如果 set 中已经存在该元素,那么我们直接放回 false ,如果 set 中不存在该元素,则将该元素放进 set 中,判断该元素是否⼩于最⼩牌,⼩于则更新最⼩牌,判断该元素是否⼤于最⼤牌,如果⼤于最⼤牌,则更新当前最⼤牌。

为什么 max - min < 5是充分必要条件?

对于5张牌组成的顺子:

  • 如果是连续5张不同数字:max - min = 4
  • 如果有空缺,但能被大小王填补:max - min ≤ 4
  • 如果空缺太大:max - min ≥ 5,即使有4个大小王也无法填补

示例验证:

  • [1,3,0,0,5]:max=5, min=1, 5-1=4<5 ✓
  • [1,6,0,0,0]:max=6, min=1, 6-1=5≥5 ✗
public class Solution45 {public boolean IsContinuous(int[] numbers) {if (numbers == null || numbers.length < 5) {return false;}HashSet <Integer> set = new HashSet <> ();int min = 14;int max = 0;for (int i = 0; i < numbers.length; i++) {if (numbers[i] != 0) {if (set.contains(numbers[i])) {return false;}set.add(numbers[i]);max = Math.max(max, numbers[i]);min = Math.min(min, numbers[i]);}}// 关键条件:最大牌-最小牌 < 5 才能组成顺子return max - min < 5;}
}
  • 时间复杂度:O(n),只需遍历数组一次
  • 空间复杂度:O(n),HashSet的空间开销

位运算法(空间最优)

利用整数的二进制位来标记牌值是否出现,实现O(1)空间复杂度。

二进制位标记原理:

  • 整数flag的32位中,用第i位表示数字i是否出现
  • 例如:数字3出现 → 将第3位置1:flag |= 1 << 3
  • 检查数字3是否出现:(flag >> 3) & 1 == 1
public class Solution {public boolean isStraight(int[] nums) {if (nums == null || nums.length != 5) {return false;}int flag = 0; // 用二进制位标记牌值出现情况int max = 0;  // 非王牌最大值int min = 14; // 非王牌最小值for (int num : nums) {if (num == 0) {continue; // 跳过大小王}// 检查牌值是否已出现(检查第num位是否为1)if (((flag >> num) & 1) == 1) {return false; // 有重复牌}// 标记牌值已出现(将第num位置为1)flag |= (1 << num);// 更新最值if (num > max) max = num;if (num < min) min = num;// 提前判断:如果已经不可能组成顺子,直接返回if (max - min >= 5) {return false;}}return max - min < 5;}
}
  • 时间复杂度:O(n),线性遍历
  • 空间复杂度:O(1),只使用固定数量的整数变量
http://www.jsqmd.com/news/59050/

相关文章:

  • 在冀州区老家农村盖房子,靠谱的自建房公司口碑推荐。河北衡水市冀州区自建房公司/机构权威测评推荐排行榜
  • pbootcms文章加了浏览权限后出现404错误
  • 2025年十大补光灯厂家排行榜,补光灯推荐厂商精选
  • 2025年中国低敏宠物狗粮企业推荐:看看哪家产品性价比高
  • 实用指南:Go语言设计模式:观察者模式详解
  • FrankenPHP 是否是 PHP 的未来?
  • PbootCMS友情链接标签调用与参数详解
  • PbootCMS网站在阿里云虚拟主机上验证码不显示原因
  • 2025年,这5个Python GUI 库让我眼前一亮​!
  • 品质筑基 服务护航:唐山汇海汽车树立二手车行业满意度新标杆
  • 国内二手车满意度调查:唐山汇海汽车以品质与保障领跑市场
  • 2025年深莞惠消防技术服务公司排名:深圳市安富消防安全技术
  • 2025年宠物功效粮品牌排行榜:鼎伴狗粮与其他品牌相比优势在
  • 大数据/AI 数据治理 - 详解
  • 百度之星 2024 决赛
  • 2025年十大专业等离子清洗机品牌排行榜,技术先进靠谱服务商
  • 2025年十大犬粮品牌排行榜:鼎伴狗粮介绍、品质评测及营养成
  • 深入解析:VBNET_图片PNG转ICO格式
  • 实用指南:【计算机视觉目标检测算法对比:R-CNN、YOLO与SSD全面解析】
  • 【URP】Unity[内置Shader]粒子光照ParticlesLit
  • 2025年国内比较好的GEO厂家排名:十大靠谱GEO企业推荐
  • 2025犬用皮肤护理食品TOP5权威推荐:鼎伴畅敏33,科学
  • 2025年国内比较好的GEO厂家年度排行榜,新测评精选GEO
  • 2025靠谱加湿器厂家TOP5推荐:精选不错的加湿器制造商
  • 2025年评价高的实验室低温冷却液循环泵/低温冷却液循环泵选型厂家最新热销排行
  • 悬臂吊服务商TOP5权威推荐:新深度测评指南,甄选企业助力工
  • 2025年服务不错的小红书代运营专业公司推荐,小红书代运营公
  • 2025年口碑好的工业低温冷却液循环泵行业内知名厂家排行榜
  • 马来西亚商标转让平台测评:2025 哪家资质全、收费明?看完直接选
  • 如何将WinForm.NET代码迁移到Blazor WASM平台上