You are given an integer array ranks
and a character array suits
. You have 5
cards where the i<sup>th</sup>
card has a rank of ranks[i]
and a suit of suits[i]
.
The following are the types of poker hands you can make from best to worst:
"Flush"
: Five cards of the same suit."Three of a Kind"
: Three cards of the same rank."Pair"
: Two cards of the same rank."High Card"
: Any single card.Return a string representing the best type of poker hand you can make with the given cards.
Examples:
ranks = [13,2,3,1,9]
, suits = ["a","a","a","a","a"]
Output: "Flush"
ranks = [4,4,2,4,4]
, suits = ["d","a","a","b","c"]
Output: "Three of a Kind"
ranks = [10,10,2,12,9]
, suits = ["a","b","c","a","d"]
Output: "Pair"
Write a function to efficiently determine the best poker hand based on the provided ranks and suits. Consider various edge cases and optimize for both time and space complexity.
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to finding the best poker hand involves checking every possible hand combination you could form from the given cards. We evaluate each combination according to the rules of poker, determining the rank of each possible hand. Finally, we identify the hand with the highest rank among all the checked combinations.
Here's how the algorithm would work step-by-step:
def best_poker_hand(ranks, suits): all_cards = list(zip(ranks, suits))
best_hand = "High Card"
card_values = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
numeric_ranks = [card_values[rank] for rank in ranks]
# Check for flush
if len(set(suits)) == 1:
best_hand = "Flush"
numeric_ranks.sort()
# Check for straight flush
if numeric_ranks == list(range(numeric_ranks[0], numeric_ranks[0] + 5)):
best_hand = "Straight Flush"
# Check for royal flush
if numeric_ranks[0] == 10:
best_hand = "Royal Flush"
return best_hand
rank_counts = {}
for rank in ranks:
rank_counts[rank] = rank_counts.get(rank, 0) + 1
# Check for four of a kind
if 4 in rank_counts.values():
return "Four of a Kind"
# Check for full house
if 3 in rank_counts.values() and 2 in rank_counts.values():
return "Full House"
numeric_ranks.sort()
# Check for straight
if len(set(numeric_ranks)) == 5 and numeric_ranks[-1] - numeric_ranks[0] == 4:
return "Straight"
# Check for three of a kind
if 3 in rank_counts.values():
return "Three of a Kind"
pair_count = sum(1 for count in rank_counts.values() if count == 2)
# Check for two pair
if pair_count == 2:
return "Two Pair"
# Check for pair
if pair_count == 1:
return "Pair"
return best_hand
To find the best poker hand, we need to check for the strongest hand first and work our way down. This avoids unnecessary checks. We can use counting to determine which hand is present without exhaustively comparing every card combination.
Here's how the algorithm would work step-by-step:
def best_poker_hand(ranks, suits):
is_flush = len(set(suits)) == 1
rank_values = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7,
'8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
numerical_ranks = sorted([rank_values[rank] for rank in ranks])
is_straight = (numerical_ranks == list(range(numerical_ranks[0], numerical_ranks[0] + 5)) or
numerical_ranks == [2, 3, 4, 5, 14])
if is_flush and is_straight:
if numerical_ranks == [10, 11, 12, 13, 14]:
return "Royal Flush"
return "Straight Flush"
rank_counts = {}
for rank in ranks:
rank_counts[rank] = rank_counts.get(rank, 0) + 1
# Determine the type of hand based on rank counts.
if 5 in rank_counts.values():
return "Four of a Kind" # Should be invalid given prior checks
if 4 in rank_counts.values():
return "Four of a Kind"
if 3 in rank_counts.values() and 2 in rank_counts.values():
return "Full House"
if is_flush:
return "Flush"
if is_straight:
return "Straight"
if 3 in rank_counts.values():
return "Three of a Kind"
pair_count = sum(1 for count in rank_counts.values() if count == 2)
if pair_count == 2:
return "Two Pair"
if pair_count == 1:
return "One Pair"
# If none of the above, return high card.
return "High Card"
Case | How to Handle |
---|---|
Null or empty input ranks or suits arrays | Return 'None' as no hand can be evaluated without cards. |
Mismatched lengths of ranks and suits arrays | Throw an IllegalArgumentException or return 'Error' since the arrays must represent a consistent hand. |
Ranks array contains invalid rank values (e.g., outside 2-14 range if using integers) | Filter out invalid ranks or throw an IllegalArgumentException. |
Suits array contains invalid suit values (e.g., not 'a', 'b', 'c', 'd') | Filter out invalid suits or throw an IllegalArgumentException. |
All cards are the same rank (e.g., five 2s) | Correctly identifies as a 'Three of a Kind', 'Pair', or 'High Card' as appropriate. |
All cards are the same suit, but not a straight | Detect Flush correctly even when not a straight. |
A straight flush is present | Prioritize and return 'Straight Flush' appropriately. |
Input hand contains duplicate cards (same rank and suit) | Return 'Error' or 'Invalid Hand', as poker hands should not contain duplicates. |