面试题:扑克牌中的顺子
题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的
2~10位数字本身,A为1,J为11,Q为12,K为13,大小王可看成任意数字
思路:
可把5张牌看成5个数字组成的数组,大小王是特殊的数字(假设定义为0)
判断5个数字是不是连续的:把数组排序,由于0可以当成任意数字,因此可以用0去补满数组中的空缺——如果排序之后的数组不是连续的,但是有足够的0可以补满两个数字之间的空缺,则也可以说这个数组是连续的
并且,如果有两个非0数字相同,则不连续
步骤:
数组排序;统计0的个数;统计需要补的空缺总数;如果总数<0的个数,则连续,反之不连续
注意:
此处排序算法的时间复杂度为O(nlogn),还不够快,由于扑克牌的值只出现在0~13之间,因此可以定义一个长度为14的哈希表,可在O(n)时间内完成排序
但通常认为不同级别的时间复杂度只有当n足够大的时候才有意义,由于本题中的数组长度是固定的,只有5,因此上面两者不会有太大的区别
代码:
public class Q61 {
public static void main(String[] args) {
int[] a = new int[] {11,9,13,0,9};
System.out.print(IsCont(a));
}
public static boolean IsCont(int[] a) {
if(a==null || a.length==0) {
return false;
}
// 排序
Arrays.sort(a);
// 0的个数和需要填补的数的个数
int zero = zeroNum(a);
int gap = gapNum(a,zero);
// gap==-1表示有重复的数
if(gap==-1) {
return false;
}
// 根据两者的个数来判断
if(gap<=zero) {
return true;
}else {
return false;
}
}
// 数组中0的个数
public static int zeroNum(int[] a) {
int m = 0;
for(int i=0;i<a.length;i++) {
if(a[i]==0) {
m++;
}else {
return m;
}
}
return m;
}
// 填补数的个数
public static int gapNum(int[] a,int zero) {
int sum = 0;
for(int i=zero;i<a.length-1;i++) {
if(a[i]==a[i+1]) {
return -1;
}
if(a[i]+1!=a[i+1]) {
sum = sum+a[i+1]-a[i]-1;
}
}
return sum;
}
}