Hand of Straights medium
Problem Statement
You are given an integer array hand
representing the hand of cards held by a player and an integer groupSize
representing the size of groups of consecutive cards.
Return true
if you can divide the cards into groups of size groupSize
such that within each group, the cards are consecutive in value. Otherwise, return false
.
Example 1:
Input: hand = [1,2,3,6,2,3,4,7,8], groupSize = 3
Output: true
Explanation:
We can group the cards as [1,2,3], [2,3,4], [6,7,8].
Example 2:
Input: hand = [1,2,3,4,5], groupSize = 4
Output: false
Explanation:
We cannot find a group of size 4 that is consecutive.
Steps and Explanation
The problem can be solved efficiently using a counter (dictionary) and a greedy approach. Here's the breakdown:
-
Count Card Frequencies: Create a counter (using
collections.Counter
) to store the frequency of each card in thehand
. This allows for quick access to the number of times each card appears. -
Iterate and Group: Iterate through the unique card values (sorted). For each card:
- Check if it's already been assigned to a group. If so, continue.
- Check if there are enough consecutive cards to form a group of size
groupSize
. This involves checking the frequency of the current card and thegroupSize - 1
subsequent cards. - If a group can be formed, decrement the counts of all the cards in the group. If at any point the count of a card goes below zero, it means we don't have enough cards to form the group, and we return
False
. - If we successfully create the group, continue to the next unique card.
-
Check for Remaining Cards: After iterating through all unique cards, check if the counter is empty. If it is, all cards have been grouped, and we return
True
. Otherwise, some cards are left ungrouped, and we returnFalse
.
Code
import collections
def isNStraightHand(hand, groupSize):
"""
Checks if a hand of cards can be divided into groups of consecutive cards.
Args:
hand: A list of integers representing the hand of cards.
groupSize: The size of the groups.
Returns:
True if the cards can be grouped, False otherwise.
"""
if len(hand) % groupSize != 0:
return False # Cannot form groups of groupSize
count = collections.Counter(hand)
sorted_cards = sorted(count.keys())
for card in sorted_cards:
if count[card] == 0:
continue
for i in range(card, card + groupSize):
if count[i] == 0:
return False # Not enough consecutive cards
count[i] -= 1
return all(c == 0 for c in count.values()) # Check if all cards are used
Complexity
- Time Complexity: O(N log N), where N is the number of cards. This is dominated by the sorting of the keys in the counter (if the input is not already sorted), and the iteration through the cards.
- Space Complexity: O(N) in the worst case to store the counter (dictionary) if all cards are unique. In the best case (many duplicates), space complexity can be less than O(N).