发布于 

剑指 Offer.61-扑克牌中的顺子

剑指 Offer.61-扑克牌中的顺子

题目链接

<剑指 Offer 61. 扑克牌中的顺子>

问题描述

从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。

个人想法

同官解相同,直接进行根据题目进行模拟

  1. 对数组进行排序
  2. 统计数组中$0$的个数
  3. 扫描整个数组,当出现不连续的情况,统计间隔的大小
  4. 在扫描过程中,出现非零重复数字直接return false
  5. 循环执行结束后,判断0的个数与间隔的大小关系,当0的个数大于等于间隔时,可直接返回true

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public boolean isStraight(int[] nums) {
//扫描一遍,扫描无序数字
Arrays.sort(nums);
int countZero = 0;
int block = 0;
for(int i = 0;i<nums.length;i++){
if(nums[i] == 0){
countZero++;
}else{
if(i > 0){
if(nums[i]-nums[i-1] == 1){
continue;
} else{
if(nums[i]-nums[i-1] == 0 && nums[i] !=0 && nums[i-1]!=0){
return false;
}else if(nums[i-1] != 0){
block += (nums[i]-nums[i-1]-1);
}
}
}
}
}

if(countZero >= block){
return true;
}else{
return false;
}
}
}

取巧解法

在当前包含大小王的牌中,若最大牌与最小牌的差值不超过5,则可构成顺子,在扫描数组时,同步更新最大值与最小值,最后执行判断即可

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 则可构成顺子
}
}

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @John Doe 创建,使用 Stellar 作为主题。