扑克牌的顺子
从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王可以看出任意数字。(出自:剑指offer)
最直观的方法是把数组排序,(把大小王看成0)由于0可以当成任意数字,我们可以用0去补满数组中的空缺,如果排序之后的数组不是连续的,即相邻的两个数字相隔若干个数字,但只要我们有足够的0可以补满这两个数字的空缺,这个数组实际上还是连续的。
于是我们需要做3件事情:首先把数组排序,再统计数组中0的个数,最后统计排序后的数组中相邻数字之间的空缺总数。如果空缺的总数小于或者等于0的个数,那么这个数组就是连续的;反之则不连续。
#include <iostream> int compare( const void *arg1, const void *arg2 ) { return *(int*)arg1 - *(int*)arg2; } bool IsContinue( int *nums, int length ) { if ( nums == NULL || length < 1 ) { return false; } std::qsort( nums, length, sizeof( int ), compare); int numOfZero = 0; int numOfGap = 0; for (int i = 0; i < length; i++) { if ( nums[ i ] == 0 ) { numOfZero++; } } int small = numOfZero; int big = small + 1; while ( big < length ) { numOfGap += nums[ big ] - nums[ small ] - 1; small = big; big++; } return ( numOfGap > numOfZero ) ? false : true; } int main() { int nums1[5] = { 1, 3, 4, 5, 0}; int nums2[5] = { 13, 12, 9, 0, 0}; int nums3[5] = { 4, 5, 6, 7, 9}; std::cout << IsContinue( nums1, 5 ) << IsContinue( nums2, 5 ) << IsContinue( nums3, 5 ) << std::endl; return 0; }