持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}
};