Problem Overview
LeetCode 1189 — Maximum Number of Balloons — gives you a string text and asks you to return the maximum number of times the word "balloon" can be formed using the characters of text. Each character in text may be used at most once per instance of "balloon" formed.
For example, given text = "nlaebolko", the answer is 1. Given text = "loonbalxballpoon", the answer is 2. Given text = "leetcode", the answer is 0 because there is no "b" in "leetcode". The challenge is tracking which characters are limiting your count.
This is an Easy-rated problem that reinforces a core string frequency pattern: count occurrences of each required character, normalize by the number of times that character appears in the target word, and take the minimum across all required characters.
- 1 <= text.length <= 10^4
- text consists of lowercase English letters only
- Target word is always "balloon" — 7 characters: b, a, l, l, o, o, n
- Each character from text can be used at most once per balloon formed
- Return the maximum number of complete "balloon" instances
Character Requirements
The word "balloon" requires exactly these characters: b appears 1 time, a appears 1 time, l appears 2 times, o appears 2 times, and n appears 1 time. The letters e, i, and other unused letters are irrelevant — you only need to track b, a, l, o, n in the input text.
To find how many balloons you can form, count how many of each required character appears in text. Then divide each count by the number of times that character is required per balloon. For b, a, n divide by 1. For l and o divide by 2. The minimum quotient (using integer division) across all five characters is your answer.
This approach works in O(n) time for the counting step and O(1) space since you only track 5 characters regardless of input size. The division step is constant work — 5 divisions and a single minimum call.
Generalizes to Any Target Word
This approach generalizes beyond "balloon": count frequencies of required characters in the source string, divide each by its required frequency in the target word, then take the minimum quotient. The same algorithm works for any target — "apple", "google", "mississippi" — with no code changes beyond the requirement map.
Frequency Counting
Use a Counter (Python) or HashMap (Java) on the full text string to get counts for every character present. You only care about the five characters in "balloon": b, a, l, o, n. All other characters can be ignored or simply left in the map unused.
Once you have the counts, the normalization is straightforward: count_b stays as-is (needed once), count_a stays as-is (needed once), count_l is divided by 2 (needed twice), count_o is divided by 2 (needed twice), count_n stays as-is (needed once). Use integer (floor) division throughout — you cannot form a fraction of a balloon.
If any required character is completely absent from text, its count will be 0. Dividing 0 by any requirement gives 0. The minimum will then be 0, correctly indicating that no complete "balloon" can be formed.
- 1Build a frequency map of all characters in text using Counter or HashMap
- 2Extract count_b = freq["b"], count_a = freq["a"], count_l = freq["l"], count_o = freq["o"], count_n = freq["n"]
- 3Normalize: divide count_l by 2 (integer division), divide count_o by 2
- 4Leave count_b, count_a, count_n unchanged (each needed exactly once)
- 5Result = min(count_b, count_a, count_l // 2, count_o // 2, count_n)
Taking the Minimum
After normalization, the result is simply: min(count_b // 1, count_a // 1, count_l // 2, count_o // 2, count_n // 1). This minimum is the bottleneck character — the one that limits how many complete "balloon" strings you can assemble, regardless of how abundant the other characters are.
If text = "balloonballoon", you have b=2, a=2, l=4, o=4, n=2. After division: l→2, o→2. The minimum across {2, 2, 2, 2, 2} is 2. You can form exactly 2 balloons. Every character is consumed perfectly with no waste in this case.
If text = "bbbaaannn", you have b=3, a=3, n=3 but l=0 and o=0. After division: l→0, o→0. The minimum is 0. Despite having plenty of b, a, and n, you cannot form a single balloon because the l and o characters are completely absent.
Supply-Chain Bottleneck Problem
This is a supply-chain bottleneck problem: the component with the lowest supply ratio determines total production capacity, regardless of how abundant other components are. The same pattern appears in manufacturing (a factory can only produce as many units as its scarcest part allows) and in resource allocation problems across system design interviews.
Walk-Through Example
Take text = "loonbalxballpoon". Let's count: b appears at positions 4 and 9 → b=2. a appears at positions 5 and 10 → a=2. l appears at positions 0, 8, 9, 11 → l=4. o appears at positions 1, 2, 12, 13 → o=4. n appears at positions 14 and implicitly — wait, let's recount. l-o-o-n-b-a-l-x-b-a-l-l-p-o-o-n: n at index 3 and index 15 → n=2. x and p are irrelevant.
Normalized counts: b=2 (÷1=2), a=2 (÷1=2), l=4 (÷2=2), o=4 (÷2=2), n=2 (÷1=2). All five normalized values equal 2. The minimum is 2. We can form exactly 2 complete "balloon" strings from this input.
Verify: first balloon uses b[0], a[0], l[0], l[1], o[0], o[1], n[0]. Second balloon uses b[1], a[1], l[2], l[3], o[2], o[3], n[1]. Every needed character is consumed, none left over. The answer of 2 is confirmed.
- 1text = "loonbalxballpoon"
- 2Count: b=2, a=2, l=4, o=4, n=2 (ignore x, p)
- 3Normalize: l÷2=2, o÷2=2; b, a, n unchanged
- 4Normalized: {b:2, a:2, l:2, o:2, n:2}
- 5min(2, 2, 2, 2, 2) = 2 balloons
Code Walkthrough — Python and Java
Python using Counter: from collections import Counter; def maxNumberOfBalloons(text): c = Counter(text); return min(c["b"], c["a"], c["l"] // 2, c["o"] // 2, c["n"]). Counter auto-initializes missing keys to 0 so no KeyError. This is O(n) time and O(1) space since the Counter has at most 26 entries.
Java approach: int[] freq = new int[26]; for (char ch : text.toCharArray()) freq[ch - 'a']++; return Math.min(freq['b'-'a'], Math.min(freq['a'-'a'], Math.min(freq['l'-'a']/2, Math.min(freq['o'-'a']/2, freq['n'-'a']))));. Using a fixed int[26] array instead of a HashMap gives O(1) space with no hashing overhead.
Both solutions run in O(n) time where n is the length of text, and O(1) space. The Python Counter allocates a small dict (at most 26 entries), while the Java array is always exactly 26 integers. Neither scales with input size beyond the constant character alphabet.
Double-Count Pitfall
Do not forget that "l" and "o" each need count // 2, not count // 1. "balloon" has double l and double o — the most common oversight on this problem. Using count["l"] directly instead of count["l"] // 2 will give an answer double what it should be for l, causing the result to overcount whenever l is the bottleneck character.