撲克牌的順子 ----《劍指offer》面試題44

題目

從撲克牌中隨機抽5張牌,判斷是不是一個順子,即這5張牌是不是連續的。2~10爲數字本身,A爲1,J爲11,Q爲12,K爲13,而大、小王可以看成任意數字。

思路

思路:把大小王看成0,把5張牌看成5個數字組成的數組。

(1)把數組排序;
(2)統計數組中0的個數。
(3)統計排序之後的數組中相鄰數字之間的空缺總數。
(4)比較“空缺”的總數是否大於0的個數,如果大於,則返回false。

時間複雜度:O(n) 雖然有排序,但是排序的數字不多。
空間複雜度:O(1)

代碼

#include <iostream>

using namespace std;

//  比較函數
int compare(const void *arg1, const void *arg2)
{
    return *(int*)arg1 - *(int*)arg2;
}

//  判斷數組中的元素能否組成一個連續的序列,0代表任意一個數
bool IsContinuous(int* numbers, int length)
{
    if (numbers == nullptr || length < 1)
        return false;

    //  排序
    qsort(numbers, length, sizeof(int), compare);

    int numberOfZero = 0;   //  0的數目
    int numberOfGap = 0;    //  代溝數,如果兩個數差距大於1,則多的那部分就是代溝

    //  統計0出現的次數
    for (int i = 0; i < length && numbers[i] == 0; ++i)
        ++numberOfZero;

    //  small、big表示兩個下標,用來統計代溝數
    //  small表示第一個非零數的下標,big表示small後的一個數
    int small = numberOfZero;
    int big = small + 1;
    while (big < length)
    {
        if (numbers[small] == numbers[big])
            return false;

        numberOfGap += numbers[big] - numbers[small] - 1;
        small = big;
        ++big;
    }

    return (numberOfGap > numberOfZero) ? false : true;
}

int main()
{
    int arr[] = {0,1,3,4,5};
    printf("arr %s continuous.\n",
        IsContinuous(arr, sizeof(arr) / sizeof(int)) ? "is" : "is not");

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章