Python 0914.py
class Solution:
def hasGroupsSizeX(self, deck: List[int]) -> bool:
if len(deck) == 1:
return False
freq = defaultdict(int)
for d in deck:
freq[d] += 1
g = freq[deck[0]]
# same greatest common divisor
for f in freq.values():
if f != g:
g = gcd(g, f)
return g > 1
Difficulty
and has an acceptance rate of about 30% (400k+ submissions).
Typical patterns to solve this problem:
- Array
- Counting
- Hash Table
- Math
- Number Theory
AI Disclaimer
However, two years later I set up this website and used various AI tools to generate most of the walkthrough / explanations below.
See this dedicated page for more details.
Code Walkthrough
Overview
The provided implementation determines whether a deck of cards can be partitioned into groups of equal size X, where X ≥ 2 and each group contains identical card values. The algorithm proceeds by counting occurrences of each distinct card, then computing the greatest common divisor (GCD) of those counts. If the resulting GCD exceeds 1, a uniform group size exists; otherwise it does not.
Key Steps
The method begins with a guard clause that immediately rejects decks containing a single card, because a group size of at least 2 cannot be formed.
if len(deck) == 1:
return False
Next, a frequency map is built using a defaultdict. This choice avoids explicit existence checks and guarantees constant-time updates for each element in the input list.
freq = defaultdict(int)
for d in deck:
freq[d] += 1
The algorithm initializes the GCD accumulator with the count of the first card value. This avoids an extra pass to locate an arbitrary non-zero count.
g = freq[deck[0]]
A single loop then iterates over all frequency values. For each value that differs from the current accumulator, the gcd function is invoked to merge the new count into the running GCD. The conditional if f != g prevents unnecessary calls when the accumulator already matches the current frequency.
for f in freq.values():
if f != g:
g = gcd(g, f)
Finally, the method returns a boolean indicating whether the computed GCD is greater than 1, which directly corresponds to the existence of a valid group size.
return g > 1
Edge Cases Handled
When the deck consists of a single element, the early return ensures the function does not attempt to compute a GCD on a trivial frequency map.
If all cards are identical, the frequency map contains a single entry; the GCD accumulator is set to that count, and the loop does not modify it. The final comparison correctly identifies that any count ≥ 2 yields a true result.
When the deck contains multiple distinct values with frequencies that share a common divisor (for example, counts of 4, 8, 12), the iterative GCD computation collapses these numbers to their greatest common divisor (in this case 4), satisfying the condition g > 1.
Conversely, if the frequencies are co-prime (e.g., counts of 3 and 5), the GCD reduces to 1, and the method returns false, reflecting the impossibility of forming equal-sized groups larger than one.
Performance Optimizations
The use of defaultdict(int) eliminates the need for conditional checks during frequency accumulation, yielding a tight O(N) loop where N is the length of the deck.
Initializing the GCD with the first frequency avoids an extra traversal to locate a non-zero count, thereby saving constant-time overhead.
The conditional if f != g before invoking gcd reduces the number of expensive GCD calculations, especially in cases where many frequencies are identical to the current accumulator.
Overall, the algorithm performs a single pass to build the frequency map and a second pass over the distinct frequencies, resulting in linear time relative to the size of the input while using only a hash map for storage.
ELI5 - Simplified Explanation
Imagine a big pile of playing cards with different numbers on them. The goal is to sort these cards into small groups so that every single group has the exact same number of cards, and every group has cards with the same number written on them.
First, the code checks if there is only one card. If there is only one, it is impossible to make a group, so the game stops there. Next, the code looks at all the cards and counts how many of each number exist. It writes these counts down in a notebook to keep track.
After counting, the code looks at those numbers to see if they can be divided into equal piles. It uses a special math trick to find a common size that fits all the groups perfectly. If it finds that it can split all the cards into groups of at least two, it confirms that the cards can be arranged nicely. If the math shows that the groups cannot be made equal, then it says that it is not possible to organize the deck in that way.
Code Quality
Complexity Analysis
Other Solutions
Obviously, I did that after I solved the problem myself.
In general, AlgoMonster and WalkCCC solutions are high-quality and always worth a look.
I haven't checked most of the other solutions, but they might be helpful as well.
And of course, the LeetCode forum is always a good place (or even the best) to look for alternative approaches.
(click on a column header to sort the table)
| author | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| author | solutions | ||||||||
| www | AlgoMonster | C++ | Python | Java | TS | ||||
| WalkCCC | C++ | Python | Java | ||||||
| leetcode.ca | C++ | Python | Java | Go | TS | ||||
| LeetcodeHelp | C++ | Python | Java | ||||||
| Progiez | C++ | Python | Java | ||||||
| github | BigEggStudy | C# | |||||||
| black-shadows | C++ | ||||||||
| charles-wangkai | Java | ||||||||
| everthis | JS | ||||||||
| fengvyi | C++ | ||||||||
| fsq | C++ | ||||||||
| halfrost | Go | ||||||||
| haoel | Python | ||||||||
| JoshCrozier | JS | ||||||||
| keineahnung2345 | C++ | ||||||||
| lkwq007 | Python | ||||||||
| lzl124631x | C++ | ||||||||
| ruoru | Rust | ||||||||
| suxrobGM | C# | ||||||||
| varunu28 | Java | ||||||||
| AlgoMonster | C++, Python, Java, TypeScript | ||||||||
| WalkCCC | C++, Python, Java | ||||||||
| leetcode.ca | C++, Go, Java, Python, TypeScript | ||||||||
| LeetcodeHelp | C++, Java, Python | ||||||||
| Progiez | C++, Java, Python | ||||||||
| BigEggStudy | C# | ||||||||
| black-shadows | C++, C++ | ||||||||
| charles-wangkai | Java | ||||||||
| everthis | JavaScript | ||||||||
| fengvyi | C++ | ||||||||
| fsq | C++ | ||||||||
| halfrost | Go | ||||||||
| haoel | Python | ||||||||
| JoshCrozier | JavaScript | ||||||||
| keineahnung2345 | C++ | ||||||||
| lkwq007 | Python | ||||||||
| lzl124631x | C++ | ||||||||
| ruoru | Rust | ||||||||
| suxrobGM | C# | ||||||||
| varunu28 | Java |
Videos
Solved On The Same Day
- problem 859: Buddy Strings
- problem 925: Long Pressed Name
- problem 1346: Check If N and Its Double Exist
- problem 1805: Number of Different Integers in a String
- problem 1909: Remove One Element to Make the Array Strictly Increasing
- problem 2047: Number of Valid Words in a Sentence
- problem 2469: Convert the Temperature
- problem 2525: Categorize Box According to Criteria
- problem 2591: Distribute Money to Maximum Children
- problem 2614: Prime In Diagonal
- problem 2660: Determine the Winner of a Bowling Game
- problem 2760: Longest Even Odd Subarray With Threshold
- problem 2765: Longest Alternating Subarray
- problem 1255: Maximum Score Words Formed by Letters
- problem 2251: Number of Flowers in Full Bloom
Extra
- Tech Stack - my development environment and tools
- AI - how AI helped me create this website (NOT solving the problems)
- Progress - progression over time
- Quality - code quality