从若干副扑克牌中随机抽 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;
    }
}
						
发表评论