题目描述
从扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。
2~10 为数字本身,A 为1,J 为 11,Q 为 12,K 为 13,大小王可以看做任意数字。
为了方便,大小王均以 0 来表示,并且假设这副牌中大小王均有两张。
样例1
输入:[8,9,10,11,12] 输出:true
样例2
输入:[0,8,9,11,12] 输出:true
解法一
- 对数组排序;
- 计算出 0 的个数
zeroCount; - 从第一个不是 0 的数字开始遍历,与后一个数字比较,如果相等,直接返回
false;否则累计gap; - 判断
zeroCount是否大于等于gap。
import java.util.Arrays;
class Solution {
/**
* 判断是否是连续的数字
*
* @param numbers 数组
* @return 是否是顺子
*/
public boolean isContinuous(int [] numbers) {
if (numbers == null || numbers.length == 0) {
return false;
}
int zeroCount = 0;
Arrays.sort(numbers);
for (int e : numbers) {
if (e > 0) {
break;
}
++zeroCount;
}
int p = zeroCount, q = p + 1, n = numbers.length;
int gap = 0;
while (q < n) {
if (numbers[p] == numbers[q]) {
return false;
}
gap += (numbers[q] - numbers[p] - 1);
p = q;
++q;
}
return gap <= zeroCount;
}
}
解二:
必须满足两个条件
1. 除0外没有重复的数
2. max - min < 5
public boolean isContinuous(int [] numbers) {
int[]d = new int[14];
d[0] = -5;
int len = numbers.length;
int max = -1;
int min = 14;
for(int i =0;i<len;i++){
d[numbers[i]]++;
f(numbers[i] == 0){
continue;
}
if(d[numbers[i]]>1){
return false;
}
if(numbers[i] >max){
max = numbers[i];
} if(numbers[i] <min){
min = numbers[i];
}
}
if(max -min<5){
return true;
}
return false;
}
或
public class Solution {
public boolean isContinuous(int [] numbers) {
if(numbers.length != 5) return false;
int min = 14;
int max = -1;
int flag = 0;
for(int i = 0; i < numbers.length; i++) {
int number = numbers[i];
if(number < 0 || number > 13) return false;
if(number == 0) continue;
if(((flag >> number) & 1) == 1) return false;
flag |= (1 << number);
if(number > max) max = number;
if(number < min) min = number;
if(max - min >= 5) return false;
}
return true;
}
}
先是用的数组做的标记,改成了用bit做标记,节省空间,效率也应该高一些