题解 | #扑克牌顺子#

扑克牌顺子

http://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4

题目难度:简单
题目考察:思维
题目内容:

  1. A为1,J为11,Q为12,K为13,A不能视为14
  2. 大、小王为 0,0可以看作任意牌
  3. 如果给出的五张牌能组成顺子(即这五张牌是连续的)就输出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;
    }
};

这种思路时间复杂度也是常数级别的,空间复杂度也是常数级别,但是思路更加暴力,更加容易想到

全部评论

相关推荐

喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务