题目

类型:贪心

image.png

解题思路

在给定 handhand 的情况下,划分方式唯一确定,因此本质上这是一个「模拟」的过程。
使用「哈希表」对 hand 中的数值进行「出现次数」统计,并用于后续 实时 维护剩余元素的出现次数。
使用优先队列维护(小根堆)所有的 hand[i]。每次从优先队列(堆)中取出堆顶元素 t 来 尝试作为「顺子」的发起点/首个元素(当然 t 能够作为发起点的前提是 t 仍是剩余元素,即实时维护的出现次数不为 0 ),然后用 t 作为发起点/首个元素构造顺子,即对 [t, t + 1, … , t + m - 1] 元素的出现次数进行 -1 操作。
若构造过程中没有出现「剩余元素出现次数」不足以 -1 的话,说明整个构造过程没有冲突,返回 True,否则返回 False。

代码

  1. class Solution {
  2. public boolean isNStraightHand(int[] hand, int groupSize) {
  3. int n = hand.length;
  4. if (n % groupSize != 0) {
  5. return false;
  6. }
  7. Arrays.sort(hand);
  8. Map<Integer, Integer> cnt = new HashMap<Integer, Integer>();
  9. for (int x : hand) {
  10. cnt.put(x, cnt.getOrDefault(x, 0) + 1);
  11. }
  12. for (int x : hand) {
  13. if (!cnt.containsKey(x)) {
  14. continue;
  15. }
  16. for (int j = 0; j < groupSize; j++) {
  17. int num = x + j;
  18. if (!cnt.containsKey(num)) {
  19. return false;
  20. }
  21. cnt.put(num, cnt.get(num) - 1);
  22. if (cnt.get(num) == 0) {
  23. cnt.remove(num);
  24. }
  25. }
  26. }
  27. return true;
  28. }
  29. }