扑克牌顺子:最直观的想法是,首先想想顺子的特点是什么。首先顺子中不能出现相同的元素,其次顺子中各元素相差值为1,如果相差值大于1,可以使用万能牌0进行补齐,同时要考虑元素之间相差值过大从而导致万能牌无法补齐的情况。具体做法如下:首先对数组进行排序,然后统计数组中0出现的次数,即可用的万能牌张数,接着遍历剩余非0元素,如果剩余元素出现相等情况,则直接返回false,即不能构成顺子,反之统计元素之间的差值,注意,此处的差值是大于正常差值1的差值,最后根据万能牌的张数与元素之间的差值比较来判断返回true还是false。

bool IsContinuous( vector<int> numbers ) 
{
    // 首先对numbers数组进行排序
    sort(numbers.begin(),numbers.end());
    // 统计数组中0出现的个数
    int i=0; //i表示下标
    int zero_num=0; //zero_num表示0的个数
    while(numbers[i]==0) //i++放在循环条件中会导致数组异位
    {
        zero_num++;
        i++;
     }
     // 遍历数组统计元素间隔
     int interdiff=0; //interdiff表示元素间隔值
     for(;(i+1)<numbers.size();i++)
     {
        // 如果出现相等元素则不能构成顺子
        if(numbers[i+1]==numbers[i])
            return false;
        // 正常的顺子元素两者之间间隔为1 其余则是补万能牌
        interdiff+=(numbers[i+1]-numbers[i]-1);
     }
     // 如果功能牌可以补齐差值则返回true反之为false
     return zero_num>=interdiff?true:false;
}

idea:既然不能出现重复元素,那么可以使用集合uset来进行处理。具体做法如下:遍历数组,如果遇到0则直接跳过,反之查找uset中是否包含该元素,如果包含则表明出现了重复元素,直接返回false,反之将该元素加入uset中,然后分别统计数组中的最大值和最小值,最后根据最大值和最小值的差值是否超过5来判断返回true还是返回false。

bool IsContinuous( vector<int> numbers ) 
{
    // 集合 用于存储除0外的非重复元素
    unordered_set<int> uset;
    // 统计最大值 最小值 数值范围1~14
    int maxn=-1,minx=15;
    // 遍历数组元素
    for(int i=0;i<numbers.size();i++)
    {
        // 如果遇到0则跳过
        if(numbers[i]==0)
           continue;
        // 遇到相同元素则返回false
        if(uset.find(numbers[i])!=uset.end())
           return false;
        // 反之加入set
        else uset.emplace(numbers[i]);
        // 统计非0最大值
        maxn=max(maxn,numbers[i]);
        // 统计非0最小值
        minx=min(minx,numbers[i]);
     }
     // 如果最大值与最小值相差不超过5则一定可以构成顺子
     return (maxn-minx+1)<=5?true:false;
}