题目来源: 1419. 数青蛙
题目描述:
- 描述: 给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 "croak" )的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs 中会混合多个 “croak” 。 请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。 要想发出蛙鸣 "croak",青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’ 这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。如果字符串 croakOfFrogs 不是由若干有效的 "croak" 字符混合而成,请返回 -1 。
- 示例:
示例1:
输入:croakOfFrogs = "croakcroak"
输出:1
解释:一只青蛙 “呱呱” 两次
示例2:
输入:croakOfFrogs = "crcoakroak"
输出:2
解释:最少需要两只青蛙,“呱呱” 声用黑体标注 第一只青蛙 "crcoakroak" 第二只青蛙 "crcoakroak"
示例2:
输入:croakOfFrogs = "croakcrook"
输出:-1
解释:给出的字符串不是 "croak" 的有效组合。
思路
思路1 题目给出一个字符串croakOfFrogs,它表示不同青蛙发出的蛙鸣声的组合,且字符串中只包含‘c’,‘r’,‘o’,‘a’ 和‘k’ 五种字符。若一只青蛙想要发出蛙鸣,则该青蛙需要依序输出‘c’,‘r’,‘o’,‘a’ 和‘k’这5 个字符。如果没有输出全部五个字符,那么它就不会发出声音。现在我们需要求得能模拟出字符串croakOfFrogs 中所有蛙鸣所需青蛙的最少数目,其中同一时间可以有多只青蛙发出声音。若字符串croakOfFrogs 不能被若干有效的蛙鸣混合而成,则返回−1。
现在我们用frog_num 来表示现在正在发出蛙鸣声的青蛙数目,用cnt[c] 表示已经发出一次有效蛙鸣中的字符c 的青蛙个数,比如当cnt[‘c’]=2 时表示当前有2 只青蛙已经发出了有效蛙鸣中的字符‘c’,下一个需要发出字符‘r’。那么我们遍历字符串croakOfFrogs 来模拟青蛙蛙鸣,现在记遍历到的字符为c,有:
- 若c=‘c’,则需要一只青蛙开始发出蛙鸣,有fog_num=fog_num+1,cnt[‘c’]=cnt[‘c’]+1。
- 否则我们记prec 为一次有效蛙鸣中该字符c 的前一个字符
- 若当前cnt[prec]=0,即没有青蛙可以发出字符c,直接返回−1。
- 否则cnt[prec]=cnt[prec]−1,cnt[c]=cnt[c]+1。且当c=‘k’ 时,说明一只青蛙完成了完整的一次蛙鸣,此时正在发出蛙鸣声的青蛙数目减一,有:fog_num=fog_num−1。
若遍历完还有正在发出蛙鸣的青蛙,即fog_num>0,说明croakOfFrogs 不是被若干有效的蛙鸣混合而成,直接返回−1。否则我们只需要返回在遍历的过程中正在发出蛙鸣的青蛙数目的最大值即可。
具体实现1
class Solution {
public int minNumberOfFrogs(String croakOfFrogs) {
if (croakOfFrogs.length() % 5 != 0) {
return -1;
}
int res = 0, frogNum = 0;
int[] cnt = new int[4];
Map<Character, Integer> map = new HashMap<Character, Integer>() {{
put('c', 0);
put('r', 1);
put('o', 2);
put('a', 3);
put('k', 4);
}};
for (int i = 0; i < croakOfFrogs.length(); i++) {
char c = croakOfFrogs.charAt(i);
int t = map.get(c);
if (t == 0) {
cnt[t]++;
frogNum++;
if (frogNum > res) {
res = frogNum;
}
} else {
if (cnt[t - 1] == 0) {
return -1;
}
cnt[t - 1]--;
if (t == 4) {
frogNum--;
} else {
cnt[t]++;
}
}
}
if (frogNum > 0) {
return -1;
}
return res;
}
}
复杂度分析1:
-
时间复杂度:O(n),其中n 为字符串croakOfFrogs 的长度。
-
空间复杂度:O(1)