字节高频面试题-846.一手顺子

解法都在代码里,不懂就留言或者私信

class Solution {
    /**第一种解法基于TreeMap */
    public boolean isNStraightHand2(int[] hand, int groupSize) {
        /**首先我们得能平均分成groupSize才行,不能分绝对不行 */
        if(hand == null || hand.length < groupSize || hand.length % groupSize != 0) {
            return false;
        }
        /**能均分的情况下我们统计一下每个数字出现了多少次,这里因为数字很大,就用hash表吧,用数组代替哈希表会很浪费空间*/
        TreeMap<Integer,Integer> countMap = new TreeMap<>();
        for(int num : hand) {
            countMap.put(num, countMap.getOrDefault(num, 0) + 1);
        }
        
        while(!countMap.isEmpty()) {
            /**我们基于当前数需要往后找多少个连续的数 */
            int count = groupSize - 1;
            /**先拿现在所有数里最小的那个 */
            int min = countMap.firstKey();
            /**我们要看看从min开始的连续的groupsize个数是不是都在map里 */
            while(count > 0) {
                /**检查的时候发现从min开始的groupSize个数有一个不在的直接返回false */
                if(!countMap.containsKey(min + count)) {
                    return false;
                }
                /**如果在的话就数量减一,如果减完是0了删除 */
                if(countMap.get(min + count) == 1) {
                    countMap.remove(min + count);
                } else {
                    countMap.put(min + count, countMap.get(min + count) - 1);
                }
                count --;  
            }
            /**以它开头的凑够了groupsize个,它也用掉了一个,数量减1,如果减成0就删除 */
            if(countMap.get(min) == 1) {
                countMap.remove(min);
            } else {
                countMap.put(min, countMap.get(min) - 1);
            }
        }
        return true;
    }
    /**第二种解法基于HashMap */
    public boolean isNStraightHand(int[] hand, int groupSize) {
        /**首先我们得能平均分成groupSize才行,不能分绝对不行 */
        if(hand == null || hand.length < groupSize || hand.length % groupSize != 0) {
            return false;
        }
        /**这里一定要先排序 */
        Arrays.sort(hand);
        /**能均分的情况下我们统计一下每个数字出现了多少次,这里因为数字很大,就用hash表吧,用数组代替哈希表会很浪费空间*/
        TreeMap<Integer,Integer> countMap = new TreeMap<>();
        for(int num : hand) {
            countMap.put(num, countMap.getOrDefault(num, 0) + 1);
        }
        
        /**再次遍历数组 */
        for(int num : hand) {
            /**数字我们用完了是要删除的,这个数有可能被前面某个数找连续的groupSize个数的时候用过了,用完了是要删除的*/
            if(!countMap.containsKey(num)) {
                continue;
            }
            /** 既然num存在,那我们就必须要用它了,并且它后面一直到num+groupSize-1个连续的数也必须存在
            这里i写成从0开始是为了用完之后删除当前的num*/
            for(int i = 0; i < groupSize; i++) {
                /**如果不存在直接return false就行了 */
                if(!countMap.containsKey(num + i)) {
                    return false;
                }
                countMap.put(num + i, countMap.get(num+i) - 1);
                if(countMap.get(num + i) == 0) {
                    countMap.remove(num + i);
                }
            }
        }
        return true;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值