题意整理
- 现在有2副扑克牌,从扑克牌中随机五张扑克牌,判断这五张牌是不是顺子。
- A为1,J为11,Q为12,K为13,A不能视为14,大小王为0,0可变成任意牌。
方法一(排序)
1.解题思路
- 首先对数组进行排序。
- 遍历整个数组,统计其中0的个数。再次遍历数组,统计其中待填补数字的个数,如果这个过程中,出现重复数字,直接返回false。
- 最后计算0的个数以及待填补数字的个数的大小,如果前者大于等于后者,说明足够填充,直接返回true。否则,返回false。
2.代码实现
import java.util.Arrays;
public class Solution {
public boolean IsContinuous(int [] numbers) {
//特殊情况判断
if(numbers==null||numbers.length==0){
return false;
}
//排序
Arrays.sort(numbers);
//记录0的个数
int numbersof0=0;
//记录待填补数字的个数
int numbersofspace=0;
for(int i=0;i<numbers.length;i++) {
if(numbers[i]==0) {
numbersof0++;
}
}
//从第二个非0的数开始遍历
for(int i=numbersof0+1;i<numbers.length;i++) {
if(numbers[i]==numbers[i-1]) {
return false;
}
//计算待填补数字的个数
numbersofspace+=numbers[i]-numbers[i-1]-1;
}
//如果足够填补,返回true
if(numbersof0>=numbersofspace) {
return true;
}
else {
return false;
}
}
}
3.复杂度分析
- 时间复杂度:需要遍历数组中所有元素,复杂度为,同时需要对数组进行排序,时间复杂度为,所以时间复杂度为。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度是。
方法二(计数)
1.解题思路
- 首先新建一个计数数组,用于统计所有牌出现的次数。
- 遍历整个数组,如果为0,直接跳过。如果不为0,并且出现次数大于1,说明重复了,直接返回false。同时计算所有牌的最小值以及最大值。
- 如果最大值与最小值之差小于5,直接返回true。否则,返回false。(简单证明:如果max、min之差小于5,除了最小值min和最大值max之外,另外三张牌要么是min、max之间,要么是0,总能填充成顺子。如果max、min之差大于等于5,则怎么也不能组成顺子,因为min作为最小值对应的顺子的最大值必定是min+4。而max>min+4,矛盾。)
图解展示:
2.代码实现
import java.util.Arrays;
public class Solution {
public boolean IsContinuous(int [] numbers) {
//特殊情况判断
if(numbers==null||numbers.length==0){
return false;
}
//统计每张牌出现的次数
int[] d=new int[14];
int max=-1;
int min=14;
for(int i=0;i<numbers.length;i++){
d[numbers[i]]++;
//为0则跳过
if(numbers[i]==0){
continue;
}
//如果出现次数大于1,说明重复了,直接返回false
if(d[numbers[i]]>1)
return false;
//更新最大值
if(numbers[i]>max){
max=numbers[i];
}
//更新最小值
if(numbers[i]<min){
min=numbers[i];
}
}
//如果最大值、最小值之间的差不超过5,则必定可组成顺子
if(max-min<5){
return true;
}
else{
return false;
}
}
}
3.复杂度分析
- 时间复杂度:需要遍历数组中所有的元素,所以时间复杂度为。
- 空间复杂度:需要额外大小为14的计数数组,为常数级别,所以空间复杂度是。