LeetCode 846 一手顺子

Alice 手中有一把牌,她想要重新排列这些牌,分成若干组,使每一组的牌数都是 groupSize ,并且由 groupSize 张连续的牌组成。

给你一个整数数组 hand 其中 hand[i] 是写在第 i 张牌,和一个整数 groupSize 。如果她可能重新排列这些牌,返回 true ;否则,返回 false

示例 1:

输入:hand = [1,2,3,6,2,3,4,7,8], groupSize = 3
输出:true
解释:Alice 手中的牌可以被重新排列为 [1,2,3],[2,3,4],[6,7,8]

示例 2:

输入:hand = [1,2,3,4,5], groupSize = 4
输出:false
解释:Alice 手中的牌无法被重新排列成几个大小为 4 的组。

提示:

  • 1 <= hand.length <= 104
  • 0 <= hand[i] <= 109
  • 1 <= groupSize <= hand.length
贪心算法+哈希
  • 利用哈希记录每个数字出现的次数
  • 遍历数字,每个牌数是否存在长度为groupSize的连续牌数,如果牌数已经在长度为groupSize的连续顺子中出现一次 ,就需要更新哈希表中该牌数出现的次数;继续统计该牌数剩余次数是否可以出现在新的连续顺子中,如果牌数的个数更新后为0,说明该牌数不会在新的顺子中出现,就需要从哈希表中移除掉;
  • 需要注意的是:数组按groupSize长度划分,说明数组长度须得是groupSize的倍数,不然是无法划分的
/**
 * 贪心算法
 * @param hand
 * @param groupSize
 * @return
 */
public static boolean isNStraightHand(int[] hand, int groupSize) {
    if (hand == null || hand.length == 0) return false;

    int n = hand.length;
    if (n % groupSize != 0) return false;

    Arrays.sort(hand);
    Map<Integer, Integer> integerMap = new TreeMap<>();
    for (int x : hand) {
        integerMap.put(x, integerMap.getOrDefault(x, 0) + 1);
    }
    // 遍历hand中元素
    for (int x : hand) {
        // 如果Map中不存在该值,判断下一个,有可能是当前值和前面的数字组成连续顺子
        if (!integerMap.containsKey(x)) {
            continue;
        }
        // 判断顺子,并更新数字出现的个数
        for (int j = 0; j < groupSize; j++) {
            int num = x + j;
            // 如果不构成顺子,则直接返回false
            if (!integerMap.containsKey(num)) {
                return false;
            }
            integerMap.put(num, integerMap.get(num) - 1);
            // 更新出现次数后为0,则移除该元素
            if (0 == integerMap.get(num)) {
                integerMap.remove(num);
            }
        }
    }
    return true;
}
测试用例
public static void main(String[] args) {
    int[] hand = new int[]{1, 2, 3, 6, 2, 3, 4, 7, 8};
    int groupSize = 3;
    boolean flag = IsNStraightHand.isNStraightHand(hand, groupSize);
    System.out.println("IsValidSudoku demo01 result : " + flag);

    hand = new int[]{1, 2, 3, 4, 5};
    groupSize = 4;
    flag = IsNStraightHand.isNStraightHand(hand, groupSize);
    System.out.println("IsValidSudoku demo02 result : " + flag);
}
测试结果
IsValidSudoku demo01 result : true
IsValidSudoku demo02 result : false
原文地址:https://www.cnblogs.com/fyusac/p/15749756.html