1419. 数青蛙
给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 "croak" )的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs 中会混合多个 “croak” 。请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。
注意:要想发出蛙鸣 "croak",青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’ 这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。
如果字符串 croakOfFrogs 不是由若干有效的 "croak" 字符混合而成,请返回 -1 。
来源:力扣(LeetCode)
链接:leetcode-cn.com/problems/mi…
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例:
输入: croakOfFrogs = "croakcroak"
输出: 1
解释: 一只青蛙 “呱呱” 两次
输入:croakOfFrogs = "crcoakroak"
输出:2
解释:最少需要两只青蛙,“呱呱” 声用大小写区分
第一只青蛙 "crcoakroak"
第二只青蛙 "CRcOAKroak"
输入: croakOfFrogs = "croakcrook"
输出: -1
解释: 给出的字符串不是 "croak " 的有效组合。
思路一 ---- 暴力循环查找(超时了 😭)
- 如果入参的长度不是 5 的倍数,肯定不是符合要求的字符串,直接返回 -1
- 符合要求的字符串,必然是以 C R O A K 这种顺序排序的,那么我们按顺序遍历,必然所有字段都可以被读取一次,否则就是不合法的,返回 -1
- 因为我们需要查找的时最少的青蛙,所以我们只要查找 字符串 中什么时候 最多c 开始,又还没有 k 结束,就可以了,比如 CRcOAKroak 这个字段,大写的 C 表示第一只青蛙开始发声,但是还没结束,小写的 c 表示第二只青蛙开始发声,大写的 K 表示第一只青蛙结束了,如果后面还有 c 那么这第一只青蛙就可以再次发声,而不需要新的一只青蛙,所以我们只需要查找最大的同时发声的青蛙,就是题目的答案!
好像思路没啥问题,但是由于遍历次数过多,时间复杂度太高,所以这种解法是超时的!
class Solution {
char[] CROAK = new char[]{'c','r','o','a','k'};
public int minNumberOfFrogs(String croakOfFrogs) {
if (croakOfFrogs.length()%5>0){
return -1;
}
char[] croaks = croakOfFrogs.toCharArray();
// 标记字符串有没有被读取过
boolean[] check = new boolean[croaks.length];
int index = 0;
// 判断是否是合法的字符串
for (int i = 0; i < croaks.length; i++) {
if(check[i]){
continue;
}
if (croaks[i] == CROAK[index]) {
index++;
check[i] = true;
}
// 如果找到一个croak,则从头开始查找下一个croak
if(index == 5){
i = 0;
index = 0;
}
}
// 当遍历结束,还有字段是没有被读取的,那么字符串不符合要求
boolean flag = true;
for (int i = 0; i < check.length; i++) {
flag = flag && check[i];
}
if(flag){
// 如果合法,则查找同时叫的青蛙的最大值
int count = 0;
int ts = 0;
for (int i = 0; i < croaks.length; i++) {
if (croaks[i]==CROAK[0]) {
// 一只青蛙开始叫了
count++;
}
if (croaks[i] == CROAK[4]){
// 一直青蛙结束了
count--;
}
ts = Math.max(count,ts);
}
return ts;
}else {
return -1;
}
}
}
思路二 ---- 一次循环 (成功了 😀)
由于暴力解法超时了,我们转换思路:
- 我们知道符合要求的字符串,必然是以 C R O A K 这种顺序排序,那必然满足有以下两点
- 青蛙叫必然是c 开始,k结束;
- 遍历字符串的任意时刻,字母的出现次数 必然是 c>r>o>a>k,否则就是不合法的
根据以上两点
class Solution {
public int minNumberOfFrogs(String croakOfFrogs) {
if (croakOfFrogs.length()%5>0){
return -1;
}
int length = croakOfFrogs.length();
char[] chars = croakOfFrogs.toCharArray();
int count = 0,ccount = 0,rcount = 0, ocount = 0, acount = 0, kcount = 0, ts = 0;
for (int i = 0; i < length; i++) {
// 遍历字符串,记录每个字符出现的次数
if (chars[i]=='c') {
ccount++;
count++;
}
if (chars[i]=='r') {
rcount++;
}
if (chars[i]=='o') {
ocount++;
}
if (chars[i]=='a') {
acount++;
}
if (chars[i] == 'k'){
kcount++;
count--;
}
if(!(ccount>=rcount&&rcount>=ocount&&ocount>=acount&&acount>=kcount)){
return -1;
}
ts = Math.max(count,ts);
}
return ts;
}
}
记录每日刷 leetcode 的思路 和 想法;
见证每 1 bit 成长;
在线蹲赞环节
老板!点赞!