题目描述
LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。
思路:大王小王相当于癞子,可以百搭,所以需要知道癞子的数量
- 想法一,根据癞子数量分类讨论。代码如下
class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
if(numbers.empty()) return false;
sort(numbers.begin(),numbers.end());
int i = 0;
while(numbers[i]==0)//统计癞子数量
{
i++;
}
if(i==4) return true;//4个癞子,必定能组成顺子
else if(i==3)//3个癞子,剩下的两张牌可以是相邻,或者为顺子的最大值和最小值,相差在1~4之间
{
if((numbers[4]-numbers[3])>=1&&(numbers[4]-numbers[3])<=4) return true;
else return false;
}
else if(i==2)//2个癞子,剩下的3张牌中最大值和最小值之差在2~4之间,2个癞子可以填充在3张牌之外,也可以填充在3张牌之间,还有一点要注意的3张牌中不能有重复的
{
if((numbers[4]-numbers[2])>=2&&(numbers[4]-numbers[2])<=4&&(numbers[4]!=numbers[3])&&(numbers[3]!=numbers[2])) return true;
else return false;
}
else if(i==1)//1个癞子,剩下的4张牌中最大值和最小值之差在3~4之间,不能有重复的牌
{
if((numbers[4]-numbers[1])>=3&&(numbers[4]-numbers[1])<=4&&(numbers[4]!=numbers[3])&&(numbers[3]!=numbers[2])&&(numbers[2]!=numbers[1])) return true;
else return false;
}
else //0个癞子,max-min==4,且不能有重复的牌
{
if((numbers[4]-numbers[0])==4&&(numbers[4]!=numbers[3])&&(numbers[3]!=numbers[2])&&(numbers[2]!=numbers[1])&&(numbers[1]!=numbers[0])) return true;
else return false;
}
}
};
- 想法二,通过上述代码,可以发现,没有癞子的情况,5张牌能组成癞子的充分必要条件:max-min==4&&不能有重复值,考虑下有癞子的情况,对已有的max和min并没有影响,对重复值也没有影响,影响的是Max-min的值,0个癞子,值为4,1个癞子,值为3或4,2个癞子,值为2,3,4,,3个癞子,值为1,2,3,4, 4个癞子必定可以组成顺子,所以癞子的数量不一定需要知道,上面的代码中,是经过排序的,经过上面的论述,发现其实不需要排序,只要记录癞子的数量,max ,min这3个值,max-min的值不能大于等于5。根据这个思路,代码如下:
class Solution {
public:
bool IsContinuous( vector<int> numbers ) {
if(numbers.empty()) return false;
int max = 0;
int min = 14;
int temp = 15;//记录上一个值,与下一个进行比对
for(int i = 0;i<numbers.size()-1;i++)
{
if(temp==numbers[i]) return false;//重复
if(numbers[i]==0)//是癞子的,则结束本次循环
{
continue;
}
if(numbers[i]>max) max = numbers[i];//记录最大值
if(numbers[i]<min) min = numbers[i];//记录最小值
temp = numbers[i];
if(max-min>=5) return false;//如果过程中出现max-min>=5说明不可能组成顺子
}
return true;
}
};
经过上面的代码,发现癞子的数量不需要知道,只要满足这二个条件即可
- 不能有重复值
- 在满足条件一的情况下,最大值减去最小值不能超过5