LeetCode 每日一题笔记
0. 前言
- 日期:2026.06.22
- 题目:1189. "气球"的最大数量
- 难度:简单
- 标签:字符串、计数、数组
1. 题目理解
问题描述 :
给定字符串 text,使用其中字母拼凑单词 balloon,每个字母只能使用一次,求最多能拼凑出多少个。
单词 balloon 字母构成:b、a、ll、oo、n,其中 l、o 每个气球需要2个,其余字母各1个。
示例:
输入:text = "nlaebolko"
输出:1
解释:每种关键字母数量仅够组成1个 balloon。
2. 解题思路
核心观察
- 统计
b,a,l,o,n五个字母的出现次数; - l、o 的可用数量需要除以2向下取整;
- 五个处理后的数字里的最小值,就是最多能拼出的气球数量。
算法步骤
- 统计目标5个字符的出现频次;
- 将 l、o 的计数除以2;
- 取五个数值的最小值作为答案。
3. 代码实现
java
package lc1189;
import java.util.HashMap;
class Solution {
public int maxNumberOfBalloons(String text) {
HashMap<String, Integer> map = new HashMap<>();
for (char c : text.toCharArray()) {
String s = String.valueOf(c);
map.put(s, map.computeIfAbsent(s, k -> 0) + 1);
}
int res = map.getOrDefault("a", 0);
if (map.getOrDefault("b", 0) < res) {
res = map.getOrDefault("b", 0);
}
if (map.getOrDefault("l", 0) / 2 < res) {
res = map.getOrDefault("l", 0) / 2;
}
if (map.getOrDefault("o", 0) / 2 < res) {
res = map.getOrDefault("o", 0) / 2;
}
if (map.getOrDefault("n", 0) < res) {
res = map.getOrDefault("n", 0);
}
return res;
}
}
4. 代码优化说明
java
class Solution {
public int maxNumberOfBalloons(String text) {
// cache[0]存储目标字符ASCII码,cache[1]存储对应计数
final int[][] cache = new int[2][5];
cache[0][0] = 97; // a
cache[0][1] = 98; // b
cache[0][2] = 108; // l
cache[0][3] = 110; // n
cache[0][4] = 111; // o
// 遍历字符串,仅统计balloon需要的5个字母
for (char ch : text.toCharArray()) {
final int intValue = ch;
for (int i = 0; i < 5; i++) {
if (intValue == cache[0][i]) {
cache[1][i]++;
break;
}
}
}
// l和o每个气球需要2个,计数整除2
cache[1][2] /= 2;
cache[1][4] /= 2;
// 遍历计数数组,取最小值,消除多层if判断
int min = Integer.MAX_VALUE;
for (int frequency: cache[1]) {
min = Math.min(min, frequency);
}
return min;
}
}
5. 复杂度分析
- HashMap 基础版
时间复杂度:O(n)O(n)O(n),n为字符串长度,多次哈希查询存在常数开销
空间复杂度:O(1)O(1)O(1),仅固定5个目标字符,哈希表容量恒定 - 数组计数优化版
时间复杂度:O(n)O(n)O(n),无哈希装箱拆箱,纯数组读写更快
空间复杂度:O(1)O(1)O(1),固定大小二维数组,无额外对象开销;消除多层if分支,用循环取最小简化逻辑
6. 总结
- 核心:统计关键字符频次,对l、o折半后取最小值;
- 优化亮点:用数组替代HashMap避免字符串装箱;循环取最小值替代多段if判断,减少分支;
- 关键点:
balloon中 l、o 各需要两个,必须整除2再参与比较。