面试题61:扑克牌中的顺子。从扑克牌中随机抽5张牌,判断是不是一个顺子,A为1,J为11,Q为12,K为13,大小王可以看做任何数字。
可以把5张牌看成由5个数字组成的数组,大小王为特殊数字,可以将它俩定义为0。之后判断这5个数字是否是连续的,最简单的方法就是将数组排序,如果排序后的数组不是连续的,即两个数字间隔若干个数字,此时只要我们有足够的0可以补满这两个数字间的空缺,那么该数组还是连续的。因此我们首先需要统计数组中0的个数,之后统计排序之后的数组中相邻数字之间空缺的总数,如果空缺数字总数小于等于0的总数,那么该数组是连续的。并且如数组中非0数字重复出现,则该数组不是连续的:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int g_NumOfPoker = 5;
bool IsContinuous(vector<int>& pokers) {
if (pokers.size() != g_NumOfPoker) {
return false;
}
sort(pokers.begin(), pokers.end());
int numOf0 = 0;
for (int i = 0; i < g_NumOfPoker; ++i) {
if (pokers[i] == 0) {
++numOf0;
}
}
int numOfGap = 0;
for (int i = numOf0; i < g_NumOfPoker - 1; ++i) {
if (pokers[i + 1] == pokers[i]) { // 如两张扑克是对子
return false;
}
numOfGap += pokers[i + 1] - pokers[i] - 1;
}
return numOf0 >= numOfGap;
}
int main() {
vector<int> pokers = { 0,1,3,4,5 };
cout << IsContinuous(pokers) << endl;
}
我们调用sort函数完成排序,它的时间复杂度为O(nlogn),我们还可以使用一个长度为14的哈希表完成排序,这样的时间复杂度为O(n),但这种差距只有在n非常大时才有意义,在本题中数组长度固定为5,因此两者差别不大,为了代码简洁使用库函数即可。