题目描述
给你一个字符串 croakOfFrogs
,它表示不同青蛙发出的蛙鸣声(字符串 "croak"
)的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs
中会混合多个 "croak"
。请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。
注意:要想发出蛙鸣 "croak"
,青蛙必须 依序 输出 'c', 'r', 'o', 'a', 'k'
这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。
如果字符串 croakOfFrogs
不是由若干有效的 "croak"
字符混合而成,请返回 -1
。
样例
输入:croakOfFrogs = "croakcroak"
输出:1
解释:一只青蛙 “呱呱” 两次。
输入:croakOfFrogs = "crcoakroak"
输出:2
解释:最少需要两只青蛙,“呱呱” 声用括号标注。
第一只青蛙 "(cr)c(oak)roak"
第二只青蛙 "cr(c)oak(roak)"
输入:croakOfFrogs = "croakcrook"
输出:-1
解释:给出的字符串不是 "croak" 的有效组合。
输入:croakOfFrogs = "croakcroa"
输出:-1
限制
1 <= croakOfFrogs.length <= 10^5
- 字符串中的字符只有
'c'
,'r'
,'o'
,'a'
或者'k'
。
算法
(贪心) $O(n)$
- 我们用四个变量分别表示当前
c
,cr
,cro
和croa
的数量。还有一个变量pending
表示当前待完成的数量。 - 当遇到
c
时,c
的数量加 1,pending
的数量加 1。 - 当遇到
r
时,如果c
的数量等于 0,则返回 -1。否则c
的数量减 1,cr
的数量加 1。 - 遇到
r
和o
同理。 - 当遇到
k
时,如果croa
的数量等于 0,则返回 -1。否则croa
数量减 1,pending
的数量减 1。 - 最后,如果
pending
的数量不为 0,则返回 -1;否则返回过程中pending
的最大值。
时间复杂度
- 仅遍历字符串一次,故时间复杂度为 $O(n)$。
空间复杂度
- 仅需要常数的额外空间。
C++ 代码
class Solution {
public:
int minNumberOfFrogs(string croakOfFrogs) {
int n = croakOfFrogs.size();
vector<int> cnt(4, 0);
int pending = 0;
int ans = 0;
for (char c : croakOfFrogs) {
if (c == 'c') {
cnt[0]++;
pending++;
} else if (c == 'r') {
if (cnt[0] == 0)
return -1;
cnt[0]--;
cnt[1]++;
} else if (c == 'o') {
if (cnt[1] == 0)
return -1;
cnt[1]--;
cnt[2]++;
} else if (c == 'a') {
if (cnt[2] == 0)
return -1;
cnt[2]--;
cnt[3]++;
} else if (c == 'k') {
if (cnt[3] == 0)
return -1;
cnt[3]--;
pending--;
}
ans = max(ans, pending);
}
if (pending > 0)
return -1;
return ans;
}
};
附一个Py版:
膜大佬