LeetCode 1419 数青蛙
题目描述
给定一个字符串 croakOfFrogs,它表示若干只青蛙发出的叫声序列。每只青蛙必须按顺序发出 'c', 'r', 'o', 'a', 'k' 五个字符才能完成一次完整的叫声。
我们需要计算完成所有叫声所需的最少青蛙数量。如果字符串无法由合法的青蛙叫声组成,则返回 -1。
解题思路
这道题的核心在于模拟青蛙的发声状态。我们可以把 'c', 'r', 'o', 'a', 'k' 看作状态机的五个阶段。
维护一个长度为 5 的数组(或哈希表),记录当前处于每个阶段的青蛙数量。遍历字符串中的每个字符时:
- 遇到 'c':这是新叫声的开始。优先复用已经完成 'k' 状态的青蛙(即上一轮叫声结束后的青蛙),如果没有可用的,则需要新增一只青蛙。
- 遇到其他字符:检查前驱状态是否有青蛙在等待。例如遇到 'r',必须有青蛙处于 'c' 状态。如果有,该青蛙进入下一阶段;如果没有,说明序列非法,直接返回 -1。
- 遍历结束:检查是否所有青蛙都完成了叫声(即都处于 'k' 状态)。如果还有青蛙停留在中间状态,说明有未完成的叫声,返回 -1。
这种方法本质上是用数组模拟了状态转移,时间复杂度为 O(N),空间复杂度为 O(1)(因为状态固定为 5 个)。
C++ 代码实现
class Solution {
public:
int minNumberOfFrogs(string croakOfFrogs) {
string s = "croak";
int n = s.size();
unordered_map<char, int> index; // 记录字符映射下标关系
vector<int> hash(n); // 数组模拟哈希表,记录各阶段青蛙数量
for (int i = 0; i < n; i++) index[s[i]] = i;
for (auto& ch : croakOfFrogs) {
if (ch == 'c') {
// 尝试复用已完成 'k' 的青蛙,否则新建
if (hash[n - 1] != 0) hash[n - 1]--;
hash[0]++;
} {
t = index[ch];
(hash[t - ] == ) ;
hash[t - ]--, hash[t]++;
}
}
( i = ; i < n - ; i++) (hash[i] != ) ;
hash[n - ];
}
};


