题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
示例 1:
输入: [1,2,3,4,5]
输出: True
示例 2:
输入: [0,0,1,2,5]
输出: True
思路:这道题我没有其他方法,因为就5个数,数据量不大,所以直接用的数学分情况讨论。
首先,由题意可知,0可以替代任何数,因此,我们先找出0的个数,当个数大于4时,是一定可以凑成顺子的;其次,开始讨论,0个个数小于4和不存在0的情况。不存在0的情况,比较简单,直接判断所有数之差是否为1。接下来,讨论有0的情况,首先先要判断数组中不为0的两个以上的数,他们之差不能大于5;其次,还需要考虑有重复数的情况,当有重复数时,不满足顺子条件。
class Solution {
public boolean isStraight(int[] nums) {
Arrays.sort(nums);
boolean flag=false;//用来记录是否存在0
int count = 0;//记录0的个数
for(int i=0;i<nums.length;i++){
if(nums[i] == 0){
count++;
flag = true;
}
}
if(count == 4 || count ==5) return true;
if(!flag){
for(int i=1;i<nums.length;i++){
if((nums[i]-nums[i-1]) !=1){
return false;
}
}
}else{
//去除重复的数
for(int i=count;i<nums.length;i++){
if((nums[i] - nums[i-1]) == 0){
return false;
}
}
//判断数之和是否大于5
if((nums[4]-nums[count]) > 5){
return false;
}
}
return true;
}
}
第二种方法:采用set集合判断重复的数
class Solution {
public boolean isStraight(int[] nums) {
Set<Integer> repeat = new HashSet<>();
int max = 0, min = 14;
for(int num : nums) {
if(num == 0) continue; // 跳过大小王
max = Math.max(max, num); // 最大牌
min = Math.min(min, num); // 最小牌
if(repeat.contains(num)) return false; // 若有重复,提前返回 false
repeat.add(num); // 添加此牌至 Set
}
return max - min < 5; // 最大牌 - 最小牌 < 5 则可构成顺子
}
}