题解 | #扑克牌顺子#
扑克牌顺子
http://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4
题目难度:简单
题目考察:思维
题目内容:
- A为1,J为11,Q为12,K为13,A不能视为14
- 大、小王为 0,0可以看作任意牌
- 如果给出的五张牌能组成顺子(即这五张牌是连续的)就输出true,否则就输出false。
题目分析:
这种题目会有各种做法,下面给出我的一种做法,首先先考虑不是0的几个数,按升序排列,如果能组成顺子,那么除了0变的牌之外左右端点一定相同,下面给出样例的过程
为什么这么考虑呢,先排序后,最小的数的左边是没数的,0选则变成左边的数是无意义的,下面给出具体考虑
这时候就已经给出一种解法了
算法1排序
下面给出代码
class Solution { public: bool IsContinuous( vector<int> numbers ) { sort(numbers.begin(),numbers.end()); //排序 int num=0,now=0,need=0; //0的个数,now当前填到的数字,need,需要多少0可以填满 for(int i=0;i<5;i++) { if(numbers[i]==0) num++; //记录0的个数 else { if(now==0) now=numbers[i]; else { if(now==numbers[i])return 0; //特判有两个数相等一定无法组成 need+=numbers[i]-now-1; //需要填0的个数 now=numbers[i]; } } } return need<=num; //0的数量够则返回1 } };
时间复杂度是常数级别的。
下面给出一种更暴力的做法
算法2
组成的顺子种类一共就11个 12345 23456...可以直接暴力每一个可不可能存在,都不存在则是false,也就是换了一种思路,给你5张牌,判断是不是 i,i+1,i+2,i+3,i+4,i+5,这时候就很容易考虑,没有的填0,没有0就就是false
下面给出代码
class Solution { public: bool IsContinuous( vector<int> numbers ) { int st[14]={0}; //记录数字出现了几次 for(int i=0;i<5;i++) st[numbers[i]]++; for(int i=1;i+4<=13;i++) { int k=st[0]; //有k个0 for(int j=i;j<=i+4;j++) { if(!st[j]) k--; //当前没有这张牌要补0 if(k<0)break; //0不够了返回 } if(k>=0)return 1; } return 0; } };
这种思路时间复杂度也是常数级别的,空间复杂度也是常数级别,但是思路更加暴力,更加容易想到