← DSA
MEDIUM

Hand of Straights

PracticeNeetCode ↗LeetCode ↗

Given an array hand of card values and an integer groupSize, determine whether the cards can be rearranged into groups of exactly groupSize consecutive values, with no leftovers.

Example

Input hand = [1,2,3,6,2,3,4,7,8], groupSize = 3
Output true

Key Pointers

Step-by-Step Analysis

  1. If len(hand) % groupSize != 0, return False.
  2. Build a count map of every card value, and a min-heap of the distinct values.
  3. While the heap isn't empty: look at the smallest value, and try to consume groupSize consecutive values starting there, decrementing each one's count.
  4. If any needed value is missing or already exhausted, return False. Pop a value from the heap once its count hits zero. Return True once every card is consumed.

Complexity

Time: O(n log n) — Space: O(n)

Code

from collections import Counter
import heapq

def isNStraightHand(hand: list[int], groupSize: int) -> bool:
    if len(hand) % groupSize != 0:
        return False

    count = Counter(hand)
    minHeap = list(count.keys())
    heapq.heapify(minHeap)

    while minHeap:
        first = minHeap[0]
        for card in range(first, first + groupSize):
            if count[card] == 0:
                return False
            count[card] -= 1
            if count[card] == 0:
                if card != minHeap[0]:
                    return False
                heapq.heappop(minHeap)

    return True

Code Explanation

How the solution above works, piece by piece.

  1. If the hand size isn't a multiple of groupSize, it can't be split → False.
  2. count holds how many of each card are left; a min-heap of distinct values gives the smallest card quickly.
  3. The smallest remaining card must begin a group, so try to take first, first+1, …. A missing card means failure.
  4. When a card's count hits 0 it must be the heap's minimum; otherwise a smaller card would be left stranded with no way to complete a group → False.
  5. O(n log n) time for the heap.

Visual Walkthrough

Running it on hand = [1, 2, 3, 6, 2, 3, 4, 7, 8], groupSize = 3:

Hand split into three straights of threesorted hand122334678group 1123smallest card left = 1 → take 1, 2, 3group 2234smallest card left = 2 → take 2, 3, 4group 3678smallest card left = 6 → take 6, 7, 8
The smallest card left must start a group (nothing smaller can come before it), so the greedy choice is forced. Taking first, first+1, first+2 each time uses every card: [1, 2, 3], [2, 3, 4], [6, 7, 8].
group 1group 2group 3

Video Explanation

NeetCode — LeetCode 846