首先对数字进行排序,排序过程中同时判断除0外是否有重复的数字,有重复则不能组成顺子。

对排好序的非0序列arr[start:end]进行计算,看要组成顺子还差几张牌,差的牌数小于等于0的个数,则能组成,否则不能组成

如2,4,7序列,则还差(4-2+1) + (7-4+1)=3张,这时只有两个0是不够的。

排序的方法可以随意。这里给出两种。

class Solution {
public:
    /*bool sort(vector<int> &numbers, int &notZeroStart)
    {
        for (int i = 0; i < numbers.size() - 1; i++)
        {
            for (int j = i + 1; j < numbers.size(); j++)
            {
                if (numbers[i] == numbers[j] && numbers[i] != 0)
                {
                    return false;
                }

                if (numbers[i] > numbers[j])
                {
                    swap(numbers[i], numbers[j]);
                }
            }
        }

        for (int i = 0; i < numbers.size(); i++)
        {
            if (numbers[i] != 0)
            {
                notZeroStart = i;
                return true;
            }
        }

        return false;
    }
    */
    //bit-map sort
    bool sort(vector<int> &numbers, int &notZeroStart)
    {
        unsigned short usBitMap = 0;
        int zeroCnt = 0;
        for (int i = 0; i < numbers.size(); i++)
        {
            numbers[i] == 0 ? zeroCnt++ : 1;
            usBitMap |=  (1 << numbers[i]);
        }

        for (int i = 0; i < zeroCnt; i++)
        {
            numbers[i] = 0;
        }

        int j = zeroCnt;
        notZeroStart = zeroCnt;
        for (int i = 1; i <= 13; i++)
        {
            if ((1 << i) & usBitMap)
            {
                numbers[j++] = i;
            }
        }
        
        return j == 5;
    }
    
    bool IsContinuous( vector<int> numbers ) {
        int notZeroStart;
        if (!sort(numbers, notZeroStart)) //除0外有重复数字返回false
        {
            return false;
        }

        int lackCnt = 0;
        for (int i = notZeroStart; i < 4; i++)
        {
            lackCnt += numbers[i + 1] - numbers[i] - 1;
        }

        return notZeroStart >= lackCnt;       
    }
};