Hand of Straights — Greedy with Ordered Frequency Map
Advertisement
Problem 196 · Hand of Straights
Difficulty: Medium · Pattern: Greedy + Ordered Map
Determine if cards can be split into groups of groupSize consecutive values.
Intuition
Sort unique cards. Always greedily form a group starting from the smallest available card.
Solutions
# Python
from collections import Counter
def isNStraightHand(hand, groupSize):
if len(hand) % groupSize: return False
cnt = Counter(hand)
for card in sorted(cnt):
if cnt[card] > 0:
n = cnt[card]
for i in range(groupSize):
if cnt[card+i] < n: return False
cnt[card+i] -= n
return True
// Java
public boolean isNStraightHand(int[] hand, int groupSize) {
if (hand.length % groupSize != 0) return false;
TreeMap<Integer,Integer> cnt = new TreeMap<>();
for (int c : hand) cnt.merge(c, 1, Integer::sum);
while (!cnt.isEmpty()) {
int first = cnt.firstKey(), n = cnt.get(first);
for (int i = 0; i < groupSize; i++) {
if (cnt.getOrDefault(first+i, 0) < n) return false;
cnt.merge(first+i, -n, Integer::sum);
if (cnt.get(first+i) == 0) cnt.remove(first+i);
}
}
return true;
}
// C++
bool isNStraightHand(vector<int>& hand, int groupSize) {
if (hand.size() % groupSize) return false;
map<int,int> cnt;
for (int c : hand) cnt[c]++;
for (auto& [card, freq] : cnt) {
if (freq > 0)
for (int i = 1; i < groupSize; i++) {
cnt[card+i] -= freq;
if (cnt[card+i] < 0) return false;
}
}
return true;
}
Complexity
- Time: O(n log n)
- Space: O(n)
Advertisement