Hand of Straights — Greedy with Ordered Frequency Map

Sanjeev SharmaSanjeev Sharma
2 min read

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

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro