846. Hand of Straights
At a Glance
- Topic: greedy
- Pattern: Greedy with ordered frequency map
- Difficulty: Medium
- Companies: Google, Amazon, Microsoft, Apple, Oracle
- Frequency: Medium
- LeetCode: 846
Problem (one-liner)
Partition multiset of integers into groups of size groupSize so each group forms consecutive values. Return whether a valid partition exists. Input: hand, groupSize. Output: boolean.
Recognition Cues
- “Consecutive in each group”
- Process from smallest value upward; each starting value uses all remaining copies as parallel group starts
- Map counts; sorted iteration or min-heap of active values
Diagram
At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.
Loading diagram…
Approaches
- Backtracking — too slow.
- Sort + greedy consumption —
O(n log n)time /O(n)space. <- pick this in interview.
Optimal Solution
Go
package main
import "sort"
func isNStraightHand(hand []int, groupSize int) bool {
if len(hand)%groupSize != 0 {
return false
}
sort.Ints(hand)
counts := make(map[int]int)
for _, value := range hand {
counts[value]++
}
for _, value := range hand {
need := counts[value]
if need == 0 {
continue
}
for offset := 0; offset < groupSize; offset++ {
card := value + offset
available := counts[card]
if available < need {
return false
}
counts[card] = available - need
}
}
return true
}JavaScript
function isNStraightHand(hand, groupSize) {
if (hand.length % groupSize !== 0) return false;
hand.sort((left, right) => left - right);
const counts = new Map();
for (const value of hand) {
counts.set(value, (counts.get(value) ?? 0) + 1);
}
for (const value of hand) {
const need = counts.get(value) ?? 0;
if (need === 0) continue;
for (let offset = 0; offset < groupSize; offset++) {
const card = value + offset;
const available = counts.get(card) ?? 0;
if (available < need) return false;
counts.set(card, available - need);
}
}
return true;
}Walkthrough
hand = [1,2,3,6,2,3,4,7,8], groupSize = 3
Sorted same order. First nonzero count at 1 is 1: form [1,2,3]. Next smallest unused drives next triples.
Edge Cases
groupSize = 1always true if empty allowed false for empty hand- Duplicates must align across parallel straights
Pitfalls
- Starting group from a value that is not locally minimal remaining
- Not decrementing counts after allocation
Similar Problems
- 056. Merge Intervals — ordering intervals after sort.
- 435. Non-overlapping Intervals — greedy after sorting.
- 045. Jump Game II — greedy layering on a different domain.
Variants
- Return actual groups → collect while greedy.
Mind-Map Tags
#greedy #frequency-map #consecutive-groups #medium
Last updated on
Spotted something unclear or wrong on this page?