参考资料:力扣K神的讲解
剑指 Offer 61. 扑克牌中的顺子
简单
351
相关企业
从若干副扑克牌中随机抽 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, 13] .
思路:
注意到 ‘0’(即大王、小王)的出现次数只有三种情况:
- ‘0’不出现
此时,可行数组(顺子)的最大值与最小值之差 为 4 - ‘0‘出现一次
此时,可行数组(顺子)的最大值与最小值之差 <= 4 - ’0‘出现两次
此时,可行数组(顺子)的最大值与最小值之差 <= 4
所以,顺子应该满足“除了0之外,最大值与最小值之差 < 5”这个数学规律。
此外,常识告诉我们:顺子不该有重复值。
综上,
检查 数组是否可行(顺子)等价于
检查 “除了0之外,最大值与最小值之差 < 5” 和 ”无重复值“ 这两个条件是否同时满足。
解法一:集合+找最大值和最小值
使用集合检查数组中是否有重复值;文章来源:https://www.toymoban.com/news/detail-647206.html
public boolean isStraight(int[] nums) {
Set<Integer> repeat = new HashSet<>();
int min=14;
int max=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==0){
continue;
}
min = Math.min(nums[i],min);
max=Math.max(nums[i],max);
if(repeat.contains(nums[i])){
return false;
}
repeat.add(nums[i]);
}
return max-min<5;
}
解法二:排序+记录0的个数
public boolean isStraight2(int[] nums) {
Arrays.sort(nums);
int count0=0;
for(int i=0;i<nums.length-1;i++){
if(nums[i]==0) {
count0++;
continue;
}
if(nums[i]==nums[i+1]) return false;// Repeat!!
}
// 遍历完成后,count0 就是 数组最小值所在位置
return nums[4]-nums[count0]<5;
}
解法三:排序+记录0的个数+记录空缺数字的个数(自己写的つ﹏⊂)
我没有观察出来那个数学规律……
这个解法的思路很朴素。
首先排序,然后遍历数组,数一下有多少”0“(作为救命稻草),有多少”缺失值“(作为坑);
遍历结束之后,看看 这些救命稻草 够不够 填补这些坑。文章来源地址https://www.toymoban.com/news/detail-647206.html
public boolean isStraight1(int[] nums) {
Arrays.sort(nums);
int count0=0;// count 0
int cnt=0;// count all the missing values
for(int i=0;i<5-1;i++){
if(nums[i]==0){
count0++;
}else{
if(nums[i]==nums[i+1]-1){
continue;
}
if(nums[i]==nums[i+1]) return false;// repeat!
cnt+=nums[i+1]-nums[i]-1;
// say, [2,3],nums[i+1]-nums[i]-1=3-2-1=0, means no missing value bwt 2 and 3
// say, [4,6], nums[i+1]-nums[i]=6-4-1=1, means there exists one missing value bwt 4 and 6
}
}
return count0>=cnt;// check if all available 0 could satisfy the demand of all missing values
}
到了这里,关于剑指 Offer ! 61. 扑克牌中的顺子的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!