若干副扑克牌中随机抽 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
  • 数组
  • 排序

  • 👍 250
  • 👎 0
  • 简单统计遍历替代处理

    简单、思路比较清晰

    1. 建一个int[] arr = new int[14];统计次数
    2. 遍历arr数组,从下标arr[1]开始,arr[0]作为特殊情况暂时留着后面有用
    3. 先遍历找到统计次数不是1的下标,表示顺子可能开始的地方,当然也可能不是从这开始的,后面会说,并开始记录连续区间的长度count
    4. 遇到的最基本的情况当前数字统计出现了1次,连续区间长度count加1
    5. 如果某个数字出现了超过1次,必然不能组成长度为5的顺子,发牌员总共就给了5张牌
    6. 如果遇到了某个数字出现次数为0,表示顺子断开了,从原来的arr[0]位置,拿一张通配牌来顶一下
    7. 如果王不够了,已经无计可施了,则直接判断此时的连续区间长度是否达到了5
    8. 如果已经遍历结束了,看下已经统计到的连续区间的长度count是否为5,如果不为5的话再看看有没有多余的通配牌,可以拿来放在当前连续区间的前面,也就是上面的第3条说的,连续区间的开始位置可能不是匹配到的位置,可能在这个位置之前拿来抵用
    9. 当然你也可能摸了5张王,而连续区间长度count为0,而arr[0] = 5,那你就是天选之人 邱森旺 了
    10. 综上最终判断其实是(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;
        }
    }