从若干副扑克牌中随机抽 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] .
Related Topics
简单统计遍历替代处理
简单、思路比较清晰
- 建一个
int[] arr = new int[14];
统计次数 - 遍历
arr
数组,从下标arr[1]
开始,arr[0]
作为特殊情况暂时留着后面有用 - 先遍历找到统计次数不是1的下标,表示顺子可能开始的地方,当然也可能不是从这开始的,后面会说,并开始记录连续区间的长度
count
- 遇到的最基本的情况当前数字统计出现了1次,连续区间长度
count
加1 - 如果某个数字出现了超过1次,必然不能组成长度为5的顺子,发牌员总共就给了5张牌
- 如果遇到了某个数字出现次数为0,表示顺子断开了,从原来的
arr[0]
位置,拿一张通配牌王
来顶一下 - 如果王不够了,已经无计可施了,则直接判断此时的连续区间长度是否达到了5
- 如果已经遍历结束了,看下已经统计到的连续区间的长度
count
是否为5,如果不为5的话再看看有没有多余的通配牌王
,可以拿来放在当前连续区间的前面,也就是上面的第3条说的,连续区间的开始位置可能不是匹配到的位置,可能在这个位置之前拿王
来抵用 - 当然你也可能摸了5张王,而连续区间长度
count
为0,而arr[0] = 5
,那你就是天选之人 (邱森旺
) 了 - 综上最终判断其实是
(count + arr[0]) == 5
代码
class Solution {
public boolean isStraight(int[] nums) {
int[] arr = new int[14];
for (int num : nums) {
arr[num]++;
}
int idx = 0;
//从1开始 可匹配任意的 0 先不管
while (++idx < arr.length && arr[idx]==0){}
idx--;
int count = 0;
while (++idx < arr.length){
if (arr[idx]>1){
//如果有一个数字出现的次数大于1了,则必然不能
return false;
}
if (arr[idx]==0){
if (arr[0]>0){
//拿 通配牌 `王` 来顶一个
count++;
arr[0]--;
}else{
// `王` 也不够顶了
return count==5;
}
}else{
//这里是等于1的情况
count++;
}
}
//可能有剩余的`王` + 已知的连续个数合起来看看能不能凑齐五个
return (count+arr[0]) == 5;
}
}
发表评论