剑指offer----061(扑克牌的顺子)

更多面试题:《剑指offer》目录索引


题目描述

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

思路

  1. 首先扑克牌是由1~13组成的,在这里的顺子指的是5张牌是不是连续的,比如1,2,3,4,5就是连续的,因此我们可以将这五张牌进行排序,在去判断是否是连续的
  2. 其次大王小王可以代替任何一个数字,故此我们可以让数字0代替大小王
  3. 这里出现顺子的情况有以下两种:

    1. 本身就是顺子,不需要0代替
    2. 需要0代替,此时需要0的个数大于中间差的个数,比如:[1, 0, 0, 5, 0 ];里面有3个0,表示可以两个数中间可以差3个连续的数,1 和 5 中间差的有2,3,4,满足这个条件,因此序列[1,0,0,5,0]就是顺子
  4. 需要注意的是当出现对子的时候不在是顺子

代码:

#include 
using namespace std;

//使用希尔排序对其进行排序
void ShellSort(int* arr, size_t length)
{
    if (arr == NULL || length < 0)
        return;

    int end = 0;
    for (size_t i = 0; i < length-1; ++i)
    {
        end = i;
        while (end >= 0 && arr[end] > arr[end + 1])
        {
            swap(arr[end], arr[end + 1]);
            --end;
        }
    }
}

bool IsContinuous(int* numbers, int length)
{
    if (numbers == NULL || length < 0)
        return false;

    //先进行排序
    ShellSort(numbers, length);

    //统计数组当中0的次数
    int count = 0;
    for (int i = 0; i < length; ++i)
    {
        if (numbers[i] == 0)
            ++count;
    }

    int cal = 0;//统计数组中不是顺序的,中间差的个数
    for (int i = 0; i < length-1; ++i)
    {
        if (numbers[i] == numbers[i + 1] && numbers[i] != 0)//当出现对子的时候不是顺子
            return false;

        if (numbers[i] != 0)
        {
            cal += numbers[i + 1] - numbers[i] - 1;//例如:0,1,2,3,5,7,则1和2之间没有相差的数,则两个差值为1,此时cal为1,故此在减一
        }
    }

    if (count >= cal)
        return true;

    return false;
}



// ====================测试代码====================
void Test(const char* testName, int* numbers, int length, bool expected)
{
    if (testName != nullptr)
        printf("%s begins: ", testName);

    if (IsContinuous(numbers, length) == expected)
        printf("Passed.\n");
    else
        printf("Failed.\n");
}

void Test1()
{
    int numbers[] = { 1, 3, 2, 5, 4 };
    Test("Test1", numbers1, sizeof(numbers1) / sizeof(int), true);
}

void Test2()
{
    int numbers[] = { 1, 3, 2, 6, 4 };
    Test("Test2", numbers, sizeof(numbers) / sizeof(int), false);
}

void Test3()
{
    int numbers[] = { 0, 3, 2, 6, 4 };
    Test("Test3", numbers, sizeof(numbers) / sizeof(int), true);
}

void Test4()
{
    int numbers[] = { 0, 3, 1, 6, 4 };
    Test("Test4", numbers, sizeof(numbers) / sizeof(int), false);
}

void Test5()
{
    int numbers[] = { 1, 3, 0, 5, 0 };
    Test("Test5", numbers, sizeof(numbers) / sizeof(int), true);
}

void Test6()
{
    int numbers[] = { 1, 3, 0, 7, 0 };
    Test("Test6", numbers, sizeof(numbers) / sizeof(int), false);
}

void Test7()
{
    int numbers[] = { 1, 0, 0, 5, 0 };
    Test("Test7", numbers, sizeof(numbers) / sizeof(int), true);
}

void Test8()
{
    int numbers[] = { 1, 0, 0, 7, 0 };
    Test("Test8", numbers, sizeof(numbers) / sizeof(int), false);
}

void Test9()
{
    int numbers[] = { 3, 0, 0, 0, 0 };
    Test("Test9", numbers, sizeof(numbers) / sizeof(int), true);
}

void Test10()
{
    int numbers[] = { 0, 0, 0, 0, 0 };
    Test("Test10", numbers, sizeof(numbers) / sizeof(int), true);
}

// 有对子
void Test11()
{
    int numbers[] = { 1, 0, 0, 1, 0 };
    Test("Test11", numbers, sizeof(numbers) / sizeof(int), false);
}

// 鲁棒性测试
void Test12()
{
    Test("Test12", nullptr, 0, false);
}

int main(int argc, char* argv[])
{
    Test1();
    Test2();
    Test3();
    Test4();
    Test5();
    Test6();
    Test7();
    Test8();
    Test9();
    Test10();
    Test11();
    Test12();


    system("pause");
    return 0;
}

结果:
剑指offer----061(扑克牌的顺子)_第1张图片

你可能感兴趣的:(剑指offer面试题)