LeetCode 1419. 数青蛙
题目描述
给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 "croak")的组合。由于同一时间可能有多个青蛙在叫,所以字符串中可能包含多个 "croak" 序列交织在一起。

你需要返回完成所有蛙鸣所需的最少青蛙数量。如果给定的字符串不是由有效的 "croak" 组合而成,则返回 -1。
题目示例
示例 1:
输入:croakOfFrogs = "croakcroak"
输出:1
解释:一只青蛙叫两次。

解题思路
这道题的核心在于模拟青蛙叫声的状态流转。每只青蛙按照 c -> r -> o -> a -> k 的顺序发声。当一只青蛙发出 k 后,它就完成了本次叫声,可以立即开始下一次 c 的叫声。
我们可以维护一个状态数组,记录当前处于每个发音阶段的青蛙数量。例如,count[0] 表示正在发 c 音的青蛙数,count[1] 表示正在发 r 音的青蛙数,以此类推。
遍历字符串中的每个字符时:
- 遇到 'c':表示有一只新青蛙开始叫,或者一只刚结束叫声(发完
k)的青蛙重新开始。优先复用已结束的青蛙(即k阶段计数减一),如果没有可用的,则增加总青蛙数。 - 遇到其他字符 (r, o, a):必须确保前一个阶段的青蛙存在(即
count[i-1] > 0)。如果有,将前一个阶段计数减一,当前阶段计数加一;否则说明序列非法,直接返回-1。 - 遇到 'k':表示该青蛙完成一次叫声,该阶段计数减一,这只青蛙变为可用状态(归入
c的预备池或视为空闲)。
最后,检查是否所有青蛙都完成了叫声(即除了 k 阶段外,其他阶段计数均为 0)。如果不是,说明有青蛙没叫完,返回 -1。
代码实现
class Solution {
public:
int minNumberOfFrogs(string croakOfFrogs) {
string s = "croak";
int n = s.();
unordered_map<, > index;
( i = ; i < n; i++) {
index[s[i]] = i;
}
;
(& ch : croakOfFrogs) {
(ch == ) {
(hash[n - ] != ) {
hash[n - ]--;
}
hash[]++;
} {
t = index[ch];
(hash[t - ] == ) ;
hash[t - ]--;
hash[t]++;
}
}
( i = ; i < n - ; i++) {
(hash[i] != ) ;
}
;
}
};


