扑克牌的顺子

题目

  从扑克牌中随机抽5张牌,判断是不是一个顺子, 即这5张牌是不是连续的。2~10为数字本身, A为1。 J为11、Q为12、 为13。小王可以看成任意数字。

思路

  接下来我们分析怎样判断5个数字是不是连续的,最直观的方法是把数组排序。值得注意的是,由于0可以当成任意数字,我们可以用0去补满数组中的空缺。如果排序之后的数组不是连续的,即相邻的两个数字相隔若干个数字,但只要我们有足够的。可以补满这两个数字的空缺,这个数组实际上还是连续的。举个例子,数组排序之后为{0,1,3,4,5}在1和3之间空缺了一个2,刚好我们有一个0,也就是我们可以把它当成2去填补这个空缺。 

  1. 首先把数组排序
  2. 再统计数组中0 的个数
  3. 最后统计排序之后的数组中相邻数字之间的空缺总数。如果空缺的总数小于或者等于0 的个数,那么这个数组就是连续的:反之则不连续。

  如果数组中的非0 数字重复出现,则该数组不是连续的。换成扑克牌的描述方式就是如果一副牌里含有对子,则不可能是顺子。

#include <iostream>
#include <algorithm>
#include <vector>
using  namespace std;

class Solution
{
    public:
        bool is_continuous(vector<int> num);
        //要求函数对象,或是静态/全局函数指针
        //非静态成员函数指针不能直接传递给std::sort,因为成员函数默认有this指针,这样和sort函数所需的排序
        //类型不一样。 
        static bool cmp(const int &a,const int &b);
};
bool Solution::cmp(const int &a,const int &b)
{
    return a<=b;
}
bool Solution::is_continuous(vector<int> num)
{
    if(num.empty()||num.size()<1)
        return false;
        
    sort(num.begin(),num.end(),Solution::cmp);
    int num_of_zero=0;
    for(int i=0;i<num.size()&&num[i]==0;++i)
        ++num_of_zero;
    
    int small=num_of_zero;
    int big=small+1;
    int num_of_grap=0;
    while(big<num.size())
    {
        if(num[small]==num[big])//有对子就不可能有顺子 
            return false;
            
        num_of_grap+=num[big]-num[small]-1;
        small=big;
        ++big;
    }
    return num_of_zero>=num_of_grap?true:false;
}
int main()
{
    Solution s;
    vector<int> num{0,1,3,4,5};
    cout<<boolalpha<<s.is_continuous(num)<<endl;    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tianzeng/p/10319502.html