剑指 Offer 61. 扑克牌中的顺子【19】

难度等级:简单

上一篇算法:

剑指 Offer 62. 圆圈中最后剩下的数字【数学】

力扣此题地址:

剑指 Offer 61. 扑克牌中的顺子 - 力扣(LeetCode)

1.题目:扑克牌中的顺子

从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。

2.解题思路:

5 张牌能否组成顺子,比如具备这个特征:5 张牌里面,除了大小王之外,所有牌均不重复,因为很显然,一旦有重复的牌,比如 1、2、2、3、4 这种牌型必然不是顺子。

根据题目描述,出现大小王的情况可以分为以下三种:

(1)5张牌里面没有大小王,那最大牌和最小牌之差为4

(2)5张牌里面有一个大小王,即出现过一个0,那最大牌与最小牌之差可能为3,可能为4

如:0、4、5、6、7,里面 0 变成了 3,组成了 3、4、5、6、7 的顺子

(3)5张牌里面出现了两个大王,即出现两个0,那最大牌与最小牌之差可能为2,也可能为3,或者为4

如: 0、0、5、6、7,里面 0 变成了 3 和 4 ,组成了 3、4、5、6、7 的顺子。

        0、4、5、0、7,里面 0 变成了 3 和 6 ,组成了 3、4、5、6、7 的顺子。

         3、0、5、0、7,里面 0 变成了 4 和 6 ,组成了 3、4、5、6、7 的顺子。

由此可以看出,顺子的情况下除了 0 之外,五张牌的最大牌与最小牌之差必然是小于 5 的。

综上所述,我们可以去遍历这 5 张牌,执行如下的操作:

  • 1、设置一个哈希表 Set,借助它来执行判重操作,判断这 5 张牌是否存在重复牌,如果存在,那么肯定就不是顺子了。
  • 2、设置两个变量 Max、Min,用来记录这五张牌除了 0 之外的最大值和最小值。
  • 3、遇到大小王,忽略它。
  • 4、遇到非大小王的牌,检查哈希表是否存在这张牌,如果存在,那么肯定就不是顺子,直接返回 false,否则将它加入到哈希表中,同时更新最大牌、最小牌的值。
  • 5、遍历完毕之后,判断 Max、Min 是否小于 5。

3.代码实现:

class Solution {
    public boolean isStraight(int[] nums) {
         // 设置一个哈希表,将 nums 中的每一个元素都放入到哈希表 cards 中
        // 在 cards 中,每一个元素值仅允许出现一次
        Set<Integer> cards = new HashSet<>();

        // 默认最小值为不可能存在的扑克牌值 14
        int min = 14;

        // 默认最大值为不可能存在的扑克牌值 0
        int max = 0;

        // 遍历 nums
        for(int num : nums) {
            // num 为 0 ,说明是大小王,跳过它
            if(num == 0) continue; 

            // 否则说明 num 不为 0,需要更新 max 和 min

            // 更新最大值 max
            max = Math.max(max, num); 

            // 更新最小值 min
            min = Math.min(min, num); 

            // 如果发现 cards 已经存在了 num,那么说明 nums 中存在了重复的扑克牌,必然无法组成顺子
            if(cards.contains(num)) return false;

            // 将这个扑克牌加入到哈希表 cards 中
            cards.add(num); 
        }

        // 遍历结束后,查看最大牌和最小牌的差值是否小于 5
        // 如果是小于 5,则可构成顺子
        // 反之,无法构成顺子
        return max - min < 5; 
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值