剑指offer:扑克牌顺子
题意描述
扑克牌有56张,大小王分别为两张。随机抽出几张牌,判断能不能组成顺子。大小王可以用0表示。并且大小王可以代替任何牌。
解题思路
一、思路一
使用辅助数组,将输入的元素对应到辅助数组之上。如果最大值max与最小值min的差值小于5,说明可以组成顺子。
- max记录最大值,min记录最小值。
- 数组元素初始为0,如果出现一个,val+1,再次出现返回false。
- 输入元素数量大于5,并且max-min《5,返回true
public boolean isContinuous(int [] numbers) {
if(numbers == null || numbers.length < 5) return false; //输入判断
int[] flag = new int[14]; //0-13,共14种输入可能
flag[0] = -5; //大小王共4张
int max = -1,min = 14;
for(int i=0;i<numbers.length;i++){
flag[numbers[i]]++; //辅助数组对应位置+1
if(numbers[i] == 0) { //遇到大小王,跳过,大小王可以看成任何值,不影响
continue;
}
if(flag[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; //最大最小差值小于5
return false;
}
二、思路二
使用Set集合元素不重复的特点,如果当前元素不为0,并且已经存在于Set集合中,返回false。
public class Solution {
public boolean isContinuous(int [] numbers) {
if(numbers == null || numbers.length < 5) return false;
HashSet<Integer> set = new HashSet<>();
int max = -1,min = 14;
for(int i=0;i<numbers.length;i++){
//当前元素不为0,并且重复
if(set.contains(numbers[i]) && numbers[i] != 0) return false;
set.add(numbers[i]);
if(numbers[i]>max && numbers[i]!=0) max = numbers[i];
if(numbers[i]<min && numbers[i]!=0) min = numbers[i];
}
if(max-min < 5) return true;
return false;
}
}
三、思路三
- 对数组进行排序,遍历输出,记录数组中0的个数。
- 如果相邻元素相同,返回false
- 计算每个相邻元素的差值的总和,如果大于0出现的次数,说明0的个数不够弥补间隔。
public boolean isContinuous(int [] numbers) {
if(numbers == null || numbers.length < 5) return false;
int count = 0; //记录0出现的次数
int interval = 0; //记录差值
Arrays.sort(numbers);
for(int i=0;i<numbers.length-1;i++){
if(numbers[i] == 0){
count++;
continue;
}
if(numbers[i] == numbers[i+1]) return false;
interval += numbers[i+1] - numbers[i] - 1; //记录相邻元素的差值总和
}
if(count >= interval){ //0的个数小于差值,返回false
return true;
}
return false;
}

浙公网安备 33010602011771号