剑指–扑克牌中的顺子
1,题目:
2,思路:
方法一:排序 + 遍历:
- 1,先对数组执行排序。,
- 2,判别重复: 排序数组中的相同元素位置相邻,因此可通过遍历数组,判断 nums[i] = nums[i +1] 是否成立来判重。,
- 3,获取最大 / 最小的牌: 排序后,数组末位元素 nums[4]为最大牌;元素nums[joker] 为最小牌,其中 joker 为大小王的数量。
下面是图解:
方法二: 集合 Set + 遍历:
(注意:方法二中的解题思路:这道题的数组里面的元素不一定非要按照严格的顺序排序的,因为是扑克牌,所以怎样放置时没有关系的,只要最大的牌,和最小的牌的数值差5就可以。)
-
遍历五张牌,遇到大小王(即 0 )直接跳过。
-
判别重复: 利用 Set 实现遍历判重, Set 的查找方法的时间复杂度为 O(1) ;
-
获取最大 / 最小的牌: 借助辅助变量 ma 和 mi ,遍历统计即可。
下面是图解:
3,代码:
方法一:排序 + 遍历:
/*
方法一:排序 + 遍历
1,先对数组执行排序。,
2,判别重复: 排序数组中的相同元素位置相邻,因此可通过遍历数组,判断 nums[i] = nums[i + 1] 是否成立来判重。,
3,获取最大 / 最小的牌: 排序后,数组末位元素 nums[4]为最大牌;元素 nums[joker] 为最小牌,其中 joker 为大小王的数量。
*/
class Solution {
public boolean isStraight(int[] nums) {
int joker = 0;
Arrays.sort(nums); // 数组排序
for(int i = 0; i < 4; i++) {
if(nums[i] == 0)
joker++; // 统计大小王数量
else if(nums[i] == nums[i + 1])
return false; // 若有重复,提前返回 false
}
return nums[4] - nums[joker] < 5; // 最大牌 - 最小牌 < 5 则可构成顺子
}
}
方法二: 集合 Set + 遍历:
class Solution {
public boolean isStraight(int[] nums) {
/*
方法一: 集合 Set + 遍历
遍历五张牌,遇到大小王(即 0 )直接跳过。
判别重复: 利用 Set 实现遍历判重, Set 的查找方法的时间复杂度为 O(1) ;
获取最大 / 最小的牌: 借助辅助变量 ma 和 mi ,遍历统计即可。
*/
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 则可构成顺子(因为不一定是严格连续)
}
}