题目: 从扑克牌中随机抽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,5中间缺2个数,这时0有2个,万能,所以true
限制:数组长度为 5 ;数组的数取值为 [0, 13] 。
我们先理解一下什么是顺子:连续且不包含对子的5张牌。
(一)常规做法,根据元素大小判断顺子 O(N)
这个题目简单理解就是判断数字顺序,:
- 首先对数组排序,因为题目给的是无序的。
- 遍历数组,a[i]==0,表示万能牌,count++;
- 判断a[i+1]-a[i]=1是否成立,成立表示顺序,不成立我们用万能牌补缺失的牌数,即count-a[i+1]-a[i]+1。
- 判断是否a[i+1]-a[i]==0,表示出现了对子,直接返回false
- 最后我们判断count<0吗,如果小于表示我们的万能牌不能弥补缺口,false;大于0表示万能牌可以。
bool isStraight(vector<int>& nums)
{
sort(nums.begin(), nums.end());//排序
int count=0;
for(int i=0;i<nums.size();i++)
{
if(nums[i]==0)//统计万能牌
{
count++;
continue;
}
if(i<nums.size()-1)//用万能牌补充顺序缺口
{
if(nums[i+1]-nums[i]!=1)
count-=(nums[i+1]-nums[i]-1);//进行补
if(nums[i+1]-nums[i]==0)//出现对子,直接错误
{
return false;
}
}
}
if(count<0)//判断是否补够了
{
return false;
}
else
return true;
}
(二)规律做法,根据牌数判断顺子 O(N)
我们先想一个事情,如果5张牌,最大数为6,最小数为2,那么需要几张牌才可以构成顺子,答案是2,3,4,5,6即6-2+1=5张牌,所以我们可以得出如果数组中最大数为m,最小数为n,那么构成顺子需要的牌数为m-n+1张。那么我们就可以通过牌数来判断是否可以构成顺子。
- 首先我们找到最大值,最小值。
- 计算所需牌数=最大值-最小值+1,如果所需牌数>5,表示不能构成顺子,false
- 如果所需牌数<=5,表示可以构成,万能牌放在合适的位置上,true,因为我们已经拿最大值最小值判断了,所以肯定可以构成。
- 还需要判断是否有一样的,一样的直接false,我们可以通过数组来标记,数组内容存储出现次数。
bool isStraight(vector<int>& nums)
{
int max=0,min=14;
vector<int>same(14,0);//判断出现次数
for(int i=0;i<nums.size();i++)
{
if(nums[i]==0)//不算万能牌
continue;
same[nums[i]]+=1;
if(same[nums[i]]>1)//出现对子
return false;
max=max>nums[i]?max:nums[i];//最大值
min=min<nums[i]?min:nums[i];//最小值
}
int count=max-min+1;
if(count<=5)
return true;
else
return false;
}
加油哦!🥘。