题目
算法思路
5张牌为顺子的充要条件为:
- 除大小王外,没有重复数字;
- 除大小王外,最大数-最小数<5
注意这里最大最小数的差值并不一定为4,当有大小王时可能小于4,例如[0,0,3,4,5]是一个顺子,但最大最小数差值为2
方法一-集合+遍历
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(num, max);//更新最大牌
min = Math.min(num, min);//更新最小牌
if(repeat.contains(num))return false;//若出现了重复的牌,直接返回false
repeat.add(num);
}
return max - min < 5;
}
}
- 时间复杂度: O ( n ) = O ( 5 ) = O ( 1 ) O(n)=O(5)=O(1) O(n)=O(5)=O(1),n 为数组长度,恒为 5。
- 空间复杂度:
O
(
n
)
=
O
(
5
)
=
O
(
1
)
O(n)=O(5)=O(1)
O(n)=O(5)=O(1),辅助集合
repeat
使用了 O ( n ) O(n) O(n)的额外空间。
方法二-排序+遍历
- 若有重复元素,则排序后必然是相邻的,所以可以用
nums[i] == nums[i+1]
来判断。 - 若数组中有
j
o
k
e
r
joker
joker 个大小王,则排序后最小的非大小王的元素为
nums[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;
}
}
- 时间复杂度: O ( n l o g n ) = O ( 5 l o g 5 ) = O ( 1 ) O(nlogn)=O(5log5)=O(1) O(nlogn)=O(5log5)=O(1),n 为数组长度,恒为 5,因为数组排序时间开销为 O ( n l o g n ) O(nlogn) O(nlogn)
- 空间复杂度: O ( 1 ) O(1) O(1),变量 j o k e r joker joker 使用 O ( 1 ) O(1) O(1) 的额外空间。