算法题每日一练---第101天:扑克牌中的顺子

1,200 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

一、问题描述

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

题目链接:扑克牌中的顺子

二、题目要求

样例 1

输入: [1,2,3,4,5]
输出: True

样例 2

输入: [0,0,1,2,5]
输出: True

考察

1.哈希表、模拟
2.建议用时10~25min

三、问题分析

这一题也是一道比较典型的思维模拟问题,首先要注意题目是从若干副牌挑选,而大小王(记为0)可以变成任意的牌。

那么我可以一口气摸出五张王,这可不能算我出老千吧!

一开始我的思路是先判断一副牌里面包含了几张0(即大小王),随后遍历所有非零的数字,找出其中的的间隙,判断这些可变化的数字能否填入其中,使其形成一个连续的顺子

后来,做出来这种方法之后,我又试着看看能不能优化一波

通常,一副顺子不包含0的话,最大差值应该为4,超过4或者包含重复元素肯定不能构成顺子了。

1 2 3 4 6
1 1 3 4 5

加入大小王0之后,对能否构成顺子的结果是不影响的,影响的只是具体的顺子数字罢了。这一题不要求求出数字,只是判断能否构成顺子。

如果还是不了解,为什么0不是一个影响因子,可以看一下这个例子:

0 1 2 3 5
0 1 2 3 10            
0 0 1 3 5
0 0 1 2 5
0 0 0 1 5
0 0 0 1 4
0 0 0 1 6
0 0 0 0 X     x代表任意数字
0 0 0 0 0

四、编码实现

class Solution {
public:
    bool isStraight(vector<int>& nums) {
        int i,mi=14,ma=0;
        map<int,int>m;
        for(i=0;i<nums.size();i++)
        {
            if(nums[i]==0)  continue;
            if(m[nums[i]])
                return false;
            m[nums[i]]++;
            mi=min(mi,nums[i]);
            ma=max(ma,nums[i]);
        }
        if(ma-mi<5)
            return true;
        else
            return false;
    }
};

五、测试结果

2.png

1.png

19.png