Intuition
The smallest remaining card must start a group, and that forces the next groupSize-1 consecutive values. Repeatedly consume such runs; if any required value is missing, it's impossible.
Explanation
Why start from the smallest
The minimum remaining card can only be the first card of some group (nothing smaller exists to precede it). So it forces a group of smallest, smallest+1, …, smallest+groupSize-1. Greedily consume that run and repeat.
Walk-through
- If
len(hand) % groupSize != 0, return false. - Count card frequencies; keep a min-heap of distinct values.
- Peek the smallest value
v. Forxin[v, v+groupSize): decrementcount[x]; if it hits 0 it must be the current heap minimum (else there's a gap) — pop it. A missingxmeans failure.
Worked example
hand = [1,2,3,6,2,3,4,7,8], groupSize = 3 → groups [1,2,3], [2,3,4], [6,7,8] → true.
Complexity
- Time: O(n log n).
- Space: O(n).
Implementation
import java.util.Map;
import java.util.TreeMap;
class Solution {
public boolean isNStraightHand(int[] hand, int groupSize) {
if (hand.length % groupSize != 0) return false;
TreeMap<Integer, Integer> count = new TreeMap<>();
for (int card : hand) {
count.merge(card, 1, Integer::sum);
}
while (!count.isEmpty()) {
int smallest = count.firstKey();
for (int x = smallest; x < smallest + groupSize; x++) {
Integer c = count.get(x);
if (c == null) return false;
if (c == 1) count.remove(x);
else count.put(x, c - 1);
}
}
return true;
}
}