问题描述:
给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"(气球)。
字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon"。示例 1:
输入:text = "nlaebolko"
输出:1示例 2:
输入:text = "loonbalxballpoon"
输出:2示例 3:
输入:text = "leetcode"
输出:0
分析:描述依然是HW的晦涩风格。其实要求很简单,字符串中剔除单词,看能剔除几次。或者理解为拆分,最多能拆出几个单词 "balloon"
解法一:顺序取字母,replace
代码如下,
public static void main(String[] args) {
String str = "nlaebolko";
// str = "loonbalxballpoon";
// str = "leetcode";
String tempStr = str;
String target = "balloon";
int maxLoop = str.length() / target.length();
int count = 0;
for (int i = 0; i < maxLoop; i++) {
str = replaceWord(str, target);
if (tempStr.length() == str.length()) {
break;
} else {
count++;
}
}
System.out.println(count);
}
// 替换,返回新单词
private static String replaceWord(String originStr, String targetStr) {
String tempStr = originStr;
// 遍历,逐个替换
for (int i = 0; i < targetStr.length(); i++) {
char c = targetStr.charAt(i);
originStr = originStr.replaceFirst(c + "", "");
}
if (tempStr.length() != originStr.length() + targetStr.length()) {
return tempStr;
}
return originStr;
}
解法2:数组+数学法
上面做法,循环replace,其实有点太蠢了,是没好思路时的笨办法。
缺点很明显,反复的生成字符串对象,反复的替换,对比。
后面我想到了新思路。将任意字符串视为一个26元素的数组,下标记录次数。
text对应数组arr1,"balloon"对应数组arr2.
这里如果还按上面思路,就是循环扣减,arr1-arr2,直到某元素为0结束。
但其实,是不用那么多次循环的。
用除法,一次获取最小除值,即为次数。
public static void main(String[] args) {
String str = "nlaebolko";
String target = "balloon";
fun2(str, target);
fun2("loonbalxballpoon", target);
fun2("leetcode", target);
}
private static void fun2(String str, String target) {
// 1.转换数组
int[] arr1 = transferArr(str);
int[] arr2 = transferArr(target);
int min = str.length();
for (int i = 0; i < arr2.length; i++) {
int cnt1 = arr2[i];
if (cnt1 == 0) continue;
min = Math.min(min, arr1[i] / cnt1);
if (min == 0) break;
}
System.out.println(min);
}
private static int[] transferArr(String str) {
int[] arr = new int[26];
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
arr[c - 'a']++;
}
return arr;
}
测试无误