从若干副扑克牌中随机抽 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]
分析:
方法1:排序
因为五张牌是连续的且只相差 1,不考虑大小王的情况下,最大牌和最小牌的差一定为 4,因为大小王也可以替补最大牌或最小牌,所以有大小王时,最大牌与最小牌的差一定小于等于4,即小于 5。因此我们可以对数组进行排序,记录最大值和最小值,0 跳过,然后判断两值之差是否小于 5 即可。注意:有重复的牌(除大小王)不算顺子。
时间复杂度:O(n*log n) n 等于 5
空间复杂度:O(n)
class Solution {
public boolean isStraight(int[] nums) {
//排序
Arrays.sort(nums);
//记录大小王个数,上一值
int king = 0, pre = 0;
//遍历
for(int n: nums){
//为大小王
if(n == 0){
king++;
}
//重复
else if(pre == n){
return false;
}
//当前值变上一值
pre = n;
}
return nums[4] - nums[king] < 5;
}
}
方法2:HashSet
利用 HashSet 不重复的特性进行去重(大小王不添加),记录最大最小值和大小王的数量,最后判断集合长度加大小王是否等于 5 和 最大最小值之差是否小于 5 即可。
时间复杂度:O(n) n 等于 5
空间复杂度:O(n)
class Solution {
public boolean isStraight(int[] nums) {
//创建集合
HashSet<Integer> set = new HashSet<>();
//定义最小最大值,大小王的数量
int min = 14, max = 0, king = 0;
//添加
for(int n: nums){
//为大小王不添加,记录数量
if(n == 0){
king++;
continue;
}
//与最大最小值比较
min = Math.min(min, n);
max = Math.max(max, n);
//添加
set.add(n);
}
return set.size() + king == 5 && max - min < 5;
}
}
题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof