Problem 2347

Abstract / Summary

Determine which poker hand is strongest among several given hands.

Note

The full problem description, including helpful examples, can be found on LeetCode.

Python 2347.py

class Solution:
    def bestHand(self, ranks: List[int], suits: List[str]) -> str:
        if len(set(suits)) == 1:
            return "Flush"

        freq = [ 0 ] * 14
        for r in ranks:
            freq[r] += 1

        same = max(freq)
        if same >= 3:
            return "Three of a Kind"
        if same == 2:
            return "Pair"

        return "High Card"
16 lines | 396 bytes | submitted February 4, 2024 | GitHub   tab size 4 | low complexity

Difficulty

This problem is ranked as
easy medium hard

and has an acceptance rate of about 62% (90k+ submissions).

Typical patterns to solve this problem:
  • Array
  • Counting
  • Hash Table
I solved 663 easy, 1250 medium and 309 hard problems

AI Disclaimer

Every single line of code was written by me, 100% from scratch, between August 2023 and August 2024.
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.
LeetCode profile | GitHub repo

Code Walkthrough

Overview

The provided Solution class implements a method bestHand that evaluates a five-card poker hand and returns a string describing its rank among a limited set of categories: “Flush”, “Three of a Kind”, “Pair”, or “High Card”. The algorithm proceeds in three logical phases: a quick flush detection, a frequency count of card ranks, and a determination of the highest matching-rank pattern based on that frequency data. The implementation is concise, leverages Python’s built-in data structures, and avoids unnecessary passes over the input.

Flush Detection

The first conditional checks whether all suits are identical. By converting the suits list to a set and comparing its length to one, the code determines if the hand is a flush in constant time.

if len(set(suits)) == 1:
    return "Flush"

This early exit handles the case where the hand qualifies as a flush regardless of rank distribution, ensuring that no further computation is performed for such hands.

Rank Frequency Counting

If the hand is not a flush, the method builds a frequency table for the card ranks. An array freq of length 14 (indices 0-13) is allocated, with index 0 unused because card ranks start at 1. Each rank from the ranks list increments the corresponding counter.

freq = [0] * 14
for r in ranks:
    freq[r] += 1

The loop iterates exactly five times, matching the fixed hand size, and populates the frequency array in place without creating auxiliary collections.

Determining the Best Hand Category

After the frequency table is populated, the algorithm extracts the maximum count of any rank using max(freq). This value, stored in same, represents the size of the largest group of identical ranks.

same = max(freq)

The subsequent conditionals map same to the appropriate hand category. If same is three or more, the hand contains at least three cards of the same rank, and the method returns “Three of a Kind”. If same equals two, a single pair is present, resulting in “Pair”. Any other value indicates that no matching ranks exist, and the method falls back to “High Card”.

if same >= 3:
    return "Three of a Kind"
if same == 2:
    return "Pair"
return "High Card"

These checks are mutually exclusive and ordered from the strongest to the weakest pattern, guaranteeing the correct classification.

Edge Cases Handled

The code gracefully handles hands where all five cards share the same suit, returning “Flush” without examining rank frequencies. It also correctly processes hands that contain multiple pairs or a full house; in such scenarios, the maximum frequency will be two for two pairs or three for a full house, leading to “Three of a Kind” for the latter and “Pair” for the former, which aligns with the limited set of categories defined. Hands with duplicate ranks beyond three (e.g., four of a kind) are also covered because the condition same >= 3 captures any count of three or more, resulting in “Three of a Kind”. The method works for any valid rank values within the 1-13 range, as the frequency array is sized to accommodate the highest possible rank index.

Performance Optimizations

The implementation exhibits several micro-optimizations. The flush check uses a set conversion, which is O(5) and terminates early for uniform suits, avoiding the cost of building the frequency table. The frequency array is pre-allocated with a fixed size, eliminating dynamic resizing and providing O(1) index access for each rank update. By using a plain list for counting rather than a dictionary, the code benefits from lower overhead and faster integer indexing. The use of max(freq) after the counting loop provides a single pass to locate the highest frequency, avoiding multiple scans or conditional counters. The early returns after each classification prevent unnecessary evaluation of later conditions, ensuring that the method exits as soon as the appropriate hand type is identified.

written by openai gpt

ELI5 - Simplified Explanation

Imagine you are playing a game with a handful of cards. This code acts like a tiny helper that looks at the cards to decide what kind of hand you are holding.

First, the helper looks at the suits. These are the different shapes on the cards like hearts or spades. If every single card has the same shape, the helper shouts out flush because that is a very special group.

If the shapes are all different, the helper starts counting how many matching numbers are in your hand. It creates a long line of buckets for every possible number. It puts your cards into these buckets to see which number appears the most times.

If the helper finds that the same number shows up three times or even more, it calls that three of a kind. If the best it can find is only two cards with the same number, it calls that a pair.

If there are no matching numbers and no matching shapes, the helper just looks at the cards and says high card, which means the hand is just a regular collection of different cards.

written by google gemini

Code Quality

Several LLMs ranked my code quality on a scale from 1 (very poor) to 10 (outstanding):
n = 27 | median = 8 | μ = 7.52 | σ = 1.13

Complexity Analysis

Time: linear
As a rule of thumb, the maximum input size for one second execution time is
  • factorial: up to 10 elements
  • exponential: up to 20 elements
  • polynomial: a few thousand elements
  • loglinear: up to 100,000 elements
  • linear: a few million elements
  • logarithmic: a billion elements
  • constant: practically unlimited
generated automatically

Other Solutions

I wrote a basic crawler to find other solutions to that problem.
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 Python Java C++ TS
WalkCCC Python Java C++
leetcode.ca Python Java C++ C Go Rust TS
Progiez Python Java C++
github charles-wangkai Java
everthis JS
fartem Ruby
fsq C++
JoshCrozier JS
lkwq007 Python
trung-hn Python
varunu28 Java
AlgoMonster C++, Python, Java, TypeScript
WalkCCC C++, Python, Java
leetcode.ca C, C++, Go, Java, Python, Rust, TypeScript
Progiez C++, Java, Python
charles-wangkai Java
everthis JavaScript
fartem Ruby
fsq C++
JoshCrozier JavaScript
lkwq007 Python
trung-hn Python
varunu28 Java
25 links | 12 authors | 9 languages

Videos

5 videos   did my crawler come up with invalid videos ? drop me a line.

Similar Problems

1 similar problem

Solved On The Same Day

5 solutions   February 4, 2024

Extra

There are a few extra pages giving you some insights into my setup:
  • 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