Given a string text
, you want to use the characters of text
to form as many instances of the word "balloon" as possible.
You can use each character in text
at most once. Return the maximum number of instances that can be formed.
Example 1:
Input: text = "nlaebolko" Output: 1
Example 2:
Input: text = "loonbalxballpoon" Output: 2
Example 3:
Input: text = "leetcode" Output: 0
Constraints:
1 <= text.length <= 104
text
consists of lower case English letters only.Note: This question is the same as 2287: Rearrange Characters to Make Target String.
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 method for this problem means trying out all possible combinations of forming the word 'balloon' from the given text. We essentially check every possible arrangement of letters to see how many complete 'balloon' words we can make. This is done by manually trying out every possible mapping between the letters in the text and the letters in 'balloon'.
Here's how the algorithm would work step-by-step:
def max_number_of_balloons_brute_force(text):
maximum_balloons = 0
def find_balloons(remaining_text, used_indices):
nonlocal maximum_balloons
found_balloon = False
for b_index in range(len(remaining_text)):
if remaining_text[b_index] == 'b' and b_index not in used_indices:
for a_index in range(len(remaining_text)):
if remaining_text[a_index] == 'a' and a_index not in used_indices:
# Need two 'l's
l_indices = [index for index in range(len(remaining_text)) if remaining_text[index] == 'l' and index not in used_indices]
if len(l_indices) < 2:
continue
for l1_index in range(len(l_indices)):
for l2_index in range(l1_index + 1, len(l_indices)):
first_l_index = l_indices[l1_index]
second_l_index = l_indices[l2_index]
# Need two 'o's
o_indices = [index for index in range(len(remaining_text)) if remaining_text[index] == 'o' and index not in used_indices]
if len(o_indices) < 2:
continue
for o1_index in range(len(o_indices)):
for o2_index in range(o1_index + 1, len(o_indices)):
first_o_index = o_indices[o1_index]
second_o_index = o_indices[o2_index]
for n_index in range(len(remaining_text)):
if remaining_text[n_index] == 'n' and n_index not in used_indices:
found_balloon = True
# Mark indices as used
new_used_indices = used_indices.copy()
new_used_indices.add(b_index)
new_used_indices.add(a_index)
new_used_indices.add(first_l_index)
new_used_indices.add(second_l_index)
new_used_indices.add(first_o_index)
new_used_indices.add(second_o_index)
new_used_indices.add(n_index)
find_balloons(remaining_text, new_used_indices)
break
if found_balloon:
break
if found_balloon:
break
if found_balloon:
break
if found_balloon:
break
if not found_balloon:
# Base case: no more balloons can be formed
balloons_formed = 0
all_indices = set(range(len(text)))
unused_indices = all_indices
maximum_balloons = max(maximum_balloons, count_balloons(text))
def count_balloons(text):
letter_counts = {}
for char in text:
letter_counts[char] = letter_counts.get(char, 0) + 1
# Integer division to determine the maximum number of balloons
num_balloons = min(
letter_counts.get('b', 0),
letter_counts.get('a', 0),
letter_counts.get('l', 0) // 2,
letter_counts.get('o', 0) // 2,
letter_counts.get('n', 0)
)
return num_balloons
# Start the recursive search with an empty set of used indices
find_balloons(text, set())
return count_balloons(text)
# Counting method to get the balloon count for a candidate set of letters.
# This is called to find the number of balloons after recursion is stopped.
The key is to realize we only need to count the occurrences of certain letters and then see how many times we can form the word 'balloon' given those counts. We focus on finding the limiting factor – the letter that appears the fewest times relative to how many times it's needed in 'balloon'.
Here's how the algorithm would work step-by-step:
def max_number_of_balloons(text):
letter_counts = {}
for letter in text:
letter_counts[letter] = letter_counts.get(letter, 0) + 1
# We only care about these letters.
balloon_letters = ['b', 'a', 'l', 'o', 'n']
required_counts = {}
for letter in balloon_letters:
if letter not in letter_counts:
return 0
# Determine how many 'balloon' words can be formed.
required_counts['b'] = letter_counts.get('b', 0)
required_counts['a'] = letter_counts.get('a', 0)
required_counts['n'] = letter_counts.get('n', 0)
# Integer division because we need a whole number of balloons.
required_counts['l'] = letter_counts.get('l', 0) // 2
# Integer division because we need a whole number of balloons.
required_counts['o'] = letter_counts.get('o', 0) // 2
# The minimum is the limiting factor.
return min(required_counts.values())
Case | How to Handle |
---|---|
Null or empty text input | Return 0, as no balloons can be formed without any characters. |
Input text shorter than the word 'balloon' | Return 0 because it's impossible to form even a single 'balloon'. |
Input text containing none of the required characters (b, a, l, o, n) | Return 0, as 'balloon' cannot be constructed. |
Input text with only one instance of 'l' or 'o' | Return 0, since 'balloon' requires two of each of these characters. |
Extremely long input string | Ensure counting operations using character frequency do not cause memory issues. |
Input text with an extremely high frequency of one particular character like 'b' | The character counts will likely limit the number of 'balloon' words formed. |
Integer overflow when counting characters | Use a data type large enough to store the counts or use modulo arithmetic. |
Input contains unicode or extended ASCII characters outside a-z. | Only count the characters 'b', 'a', 'l', 'o', and 'n' and ignore all others |