Hand of Straights. — Cracked Java
// Data Structures & Algorithms · Greedy Algorithms
MidCoding

Hand of Straights.

Problem. Given an array hand of card values and a groupSize, determine whether the cards can be rearranged into groups of groupSize consecutive values. (LeetCode also calls this "Divide Array in Sets of K Consecutive Numbers.")

Greedy idea — always start a straight at the smallest remaining card

The smallest available card must be the start of some straight — nothing smaller exists to precede it. So greedily form a straight beginning at the current minimum, consuming min, min+1, ..., min+groupSize-1. If any required card is missing, it's impossible.

TreeMap solution — O(n log n)

A TreeMap<value, count> keeps values sorted (cheap access to the minimum) and tracks remaining counts.

boolean isNStraightHand(int[] hand, int groupSize) {
    if (hand.length % groupSize != 0) return false;          // must divide evenly

    TreeMap<Integer, Integer> count = new TreeMap<>();
    for (int c : hand) count.merge(c, 1, Integer::sum);

    while (!count.isEmpty()) {
        int start = count.firstKey();                        // smallest remaining card
        for (int v = start; v < start + groupSize; v++) {
            Integer have = count.get(v);
            if (have == null) return false;                  // missing card -> fail
            if (have == 1) count.remove(v);
            else count.put(v, have - 1);
        }
    }
    return true;
}

Why the greedy choice is safe

The minimum card cannot be the middle or end of any straight (no smaller value exists), so it can only be a start. Once we fix that, consuming the next groupSize - 1 consecutive values is forced. There's never a choice to second-guess — hence greedy, not DP.

Complexity note

firstKey() and each get/put are O(log n). We touch each card once across all straights, so total work is O(n log n). An alternative uses a HashMap plus a sort of the distinct keys for the same bound; the TreeMap is cleaner because it maintains the sorted order incrementally.

OperationBestAverageWorstNote
TreeMap greedyO(n log n)O(n log n)O(n log n)sorted-map ops; O(n) space

Mark your status