Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 1189. Maximum Number of Balloons

[LeetCode Link](https://leetcode.com/problems/maximum-number-of-balloons/)

Difficulty: Easy
Topics: Hash Table, String, Counting
Acceptance Rate: 61.4%

## Hints

### Hint 1

The order of the characters in `text` does not matter — you are only allowed to *reuse* each character once to build copies of a fixed target word. When order is irrelevant and you only care about *how many of each item you have*, think about **counting** rather than scanning or two pointers.

### Hint 2

Count how many times each letter appears in `text`. Then compare those counts against the letters needed for one copy of `"balloon"`. The answer is limited by whichever required letter "runs out" first.

### Hint 3

The word `"balloon"` needs the letters `b, a, n` once each and `l, o` **twice** each. So for `l` and `o`, the number of complete copies they can support is `count / 2` (integer division). The maximum number of balloons is the **minimum** over all five required letters of (available count ÷ needed count).

## Approach

This is a classic frequency-counting problem.

1. **Tally `text`.** Walk through `text` once and build a frequency table of all 26 lowercase letters. An array of size 26 (indexed by `c - 'a'`) is the cleanest container, but a map works equally well.

2. **Identify the requirement.** The target word `"balloon"` is composed of:
- `b` × 1
- `a` × 1
- `l` × 2
- `o` × 2
- `n` × 1

Only these five distinct letters matter; every other letter in `text` is irrelevant.

3. **Bottleneck = minimum ratio.** Each complete copy of `"balloon"` consumes the letters above. If you have, say, 5 `l`'s, you can only contribute `5 / 2 = 2` copies from the `l` supply. Apply this for every required letter and take the smallest result — that letter is the bottleneck that caps how many full words you can spell.

- For `b`, `a`, `n`: copies supported = `count`
- For `l`, `o`: copies supported = `count / 2`

Answer = `min(count[b], count[a], count[l]/2, count[o]/2, count[n])`.

**Example:** `text = "loonbalxballpoon"`.
Counts: `b=2, a=2, l=4, o=4, n=2` (the `x`, `p` are ignored).
- `b`: 2, `a`: 2, `n`: 2
- `l`: 4/2 = 2, `o`: 4/2 = 2

The minimum is `2`, so the answer is `2`. ✅

Why it works: spelling each copy is independent and consumes a fixed letter cost, so the total is purely supply-limited by the scarcest required letter relative to its per-word demand.

## Complexity Analysis

Time Complexity: O(n), where n is the length of `text` — a single pass to count, then O(1) work to compare the five required letters.
Space Complexity: O(1) — a fixed-size table of 26 counters regardless of input size.

## Edge Cases

- **No matching letters / missing a required letter** (e.g. `"leetcode"`): if any of `b, a, l, o, n` is absent, its count is 0, the minimum is 0, and the answer is correctly `0`.
- **The double letters `l` and `o`**: the most common mistake is treating every letter as needing one occurrence. Forgetting the integer division by 2 for `l` and `o` produces wrong (too-large) answers.
- **Exactly enough letters for one word** (e.g. `"balloon"` or `"nlaebolko"`): all ratios equal 1, answer is 1 — verifies the boundary.
- **Extra irrelevant characters**: letters not in `"balloon"` should not affect the count; the algorithm naturally ignores them.
- **Short input** (length 1): cannot form a word, returns 0.
63 changes: 63 additions & 0 deletions problems/1189-maximum-number-of-balloons/problem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
number: "1189"
frontend_id: "1189"
title: "Maximum Number of Balloons"
slug: "maximum-number-of-balloons"
difficulty: "Easy"
topics:
- "Hash Table"
- "String"
- "Counting"
acceptance_rate: 6142.7
is_premium: false
created_at: "2026-06-22T05:40:12.909302+00:00"
fetched_at: "2026-06-22T05:40:12.909302+00:00"
link: "https://leetcode.com/problems/maximum-number-of-balloons/"
date: "2026-06-22"
---

# 1189. Maximum Number of Balloons

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:**

**![](https://assets.leetcode.com/uploads/2019/09/05/1536_ex1_upd.JPG)**


**Input:** text = "nlaebolko"
**Output:** 1


**Example 2:**

**![](https://assets.leetcode.com/uploads/2019/09/05/1536_ex2_upd.JPG)**


**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.](https://leetcode.com/problems/rearrange-characters-to-make-target-string/description/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

// Maximum Number of Balloons
//
// Approach: frequency counting. Count every letter in text, then for each of the
// five letters that make up "balloon" (b, a, l, o, n) compute how many complete
// copies it can support — dividing by 2 for the doubled letters l and o. The
// answer is the minimum across those five, since the scarcest required letter is
// the bottleneck.
//
// Time: O(n) for a single pass over text.
// Space: O(1) using a fixed 26-element counter.
func maxNumberOfBalloons(text string) int {
var count [26]int
for _, c := range text {
count[c-'a']++
}

// Letters needed for one "balloon": b, a, n once each; l, o twice each.
candidates := []int{
count['b'-'a'],
count['a'-'a'],
count['l'-'a'] / 2,
count['o'-'a'] / 2,
count['n'-'a'],
}

best := candidates[0]
for _, c := range candidates[1:] {
if c < best {
best = c
}
}
return best
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import "testing"

func TestMaxNumberOfBalloons(t *testing.T) {
tests := []struct {
name string
text string
expected int
}{
{"example 1: single balloon from scrambled letters", "nlaebolko", 1},
{"example 2: two balloons with extra letters", "loonbalxballpoon", 2},
{"example 3: no balloon possible", "leetcode", 0},
{"edge case: exact balloon spelling", "balloon", 1},
{"edge case: missing required letter n", "balloo", 0},
{"edge case: single character", "b", 0},
{"edge case: enough singles but only one l", "balon", 0},
{"edge case: three balloons", "balloonballoonballoon", 3},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := maxNumberOfBalloons(tt.text)
if result != tt.expected {
t.Errorf("maxNumberOfBalloons(%q) = %d, want %d", tt.text, result, tt.expected)
}
})
}
}