{x}
blog image

X of a Kind in a Deck of Cards

You are given an integer array deck where deck[i] represents the number written on the ith card.

Partition the cards into one or more groups such that:

  • Each group has exactly x cards where x > 1, and
  • All the cards in one group have the same integer written on them.

Return true if such partition is possible, or false otherwise.

 

Example 1:

Input: deck = [1,2,3,4,4,3,2,1]
Output: true
Explanation: Possible partition [1,1],[2,2],[3,3],[4,4].

Example 2:

Input: deck = [1,1,1,2,2,2,3,3]
Output: false
Explanation: No possible partition.

 

Constraints:

  • 1 <= deck.length <= 104
  • 0 <= deck[i] < 104

Solution Explanation: X of a Kind in a Deck of Cards

This problem asks whether it's possible to partition a deck of cards into groups, where each group contains the same number of cards (x, and x > 1), and all cards within a group have the same value.

Approach:

The core idea is to find the greatest common divisor (GCD) of the counts of each card value in the deck. If this GCD is greater than 1, then we can partition the cards into groups of size GCD, fulfilling the problem's conditions. If the GCD is 1 or less, it's not possible to create such groups.

Algorithm:

  1. Count Card Occurrences: Use a hash map (dictionary in Python) or similar data structure to count the number of times each card value appears in the deck.

  2. Calculate GCD: Compute the GCD of all the counts obtained in step 1. The Euclidean algorithm is efficient for this.

  3. Check GCD: If the GCD is greater than or equal to 2, return true (partition is possible); otherwise, return false.

Time Complexity Analysis:

  • Counting Card Occurrences: This step iterates through the deck once, which takes O(n) time, where n is the length of the deck.

  • Calculating GCD: The Euclidean algorithm for finding the GCD of two numbers has a time complexity of O(log min(a, b)), where 'a' and 'b' are the two numbers. Since we calculate the GCD iteratively across all counts, and assuming the average number of unique cards is constant, this step has an overall time complexity of O(n log m) in the worst case, where 'm' is the maximum count of any single card. In practice, for reasonably sized decks, this can be considered approximately linear because the GCD calculation cost is often small compared to the card counting step.

  • Checking GCD: This is a constant-time operation, O(1).

Therefore, the overall time complexity is dominated by the counting and GCD calculation steps, resulting in O(n log m) or approximately O(n) in practice.

Space Complexity Analysis:

The space complexity is determined by the size of the hash map used to store the card counts. In the worst-case scenario, where all cards have unique values, the space complexity would be O(n). However, usually, the number of unique cards will be much smaller than n, making the space complexity closer to O(k) where k is the number of unique cards in the deck.

Code Examples (with explanations):

The code examples provided previously demonstrate the solution in different programming languages. Here is a breakdown of a Python example:

from collections import Counter
from math import gcd  # Use the built-in gcd function
 
def hasGroupsSizeX(deck):
    """
    Checks if a deck of cards can be partitioned into groups with equal size and card values.
 
    Args:
      deck: A list of integers representing the card values.
 
    Returns:
      True if a partition is possible, False otherwise.
    """
    counts = Counter(deck)  #Efficiently counts card occurrences
    if not counts: #Handle empty deck
        return False
    
    #Calculate GCD of all counts using reduce (functional approach)
    g = counts.values().__next__() #start with the first count in the list
    for count in counts.values():
        g = gcd(g,count) #Efficient GCD Calculation using the built-in gcd
 
    return g >= 2 #Check if GCD is at least 2
 
 

This Python example leverages the Counter object for efficient counting and the built-in gcd function for a concise solution. The other language examples follow a similar structure, adapting to their respective language features. They all adhere to the same fundamental algorithm for solving the problem.