【LeetCode 每日一题】1419. 数青蛙

106 阅读1分钟

1419. 数青蛙

难度:中等

时间:2023/05/07


给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 "croak" )的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs 中会混合多个 “croak”

请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。

要想发出蛙鸣 "croak",青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’ 这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。如果字符串 croakOfFrogs 不是由若干有效的 "croak" 字符混合而成,请返回 -1

示例 1:

输入:croakOfFrogs = "croakcroak"
输出:1 
解释:一只青蛙 “呱呱” 两次

示例 2:

输入:croakOfFrogs = "crcoakroak"
输出:2 
解释:最少需要两只青蛙,“呱呱” 声用黑体标注
第一只青蛙 "crcoakroak"
第二只青蛙 "crcoakroak"

示例 3:

输入:croakOfFrogs = "croakcrook"
输出:-1
解释:给出的字符串不是 "croak" 的有效组合。

提示:

  • 1 <= croakOfFrogs.length <= 10^5
  • 字符串中的字符只有 'c', 'r', 'o', 'a' 或者 'k'

解题思路:

  • 首先是计数,创建五个变量c,r,o,a,k,依次遍历croakOfFrogs中的每一个字符,出现某个字母便将其前面的字母对应数量减一,同时将该字母加一(c除外,下面将单独讨论)。遍历过程中,如果出现某个字母数量小于零的情况,就是出现了不匹配的问题,此时直接返回-1即可。
  • 在遍历到c时,我们注意到这是一次新的croak的开始,我们需要对前面的青蛙是否叫完进行判断,此时k便起到了重要的作用,我们每出现一次k,便代表了有一只青蛙叫完,当k大于0时,代表着有闲置的已叫过的青蛙,也就是说此时是不需要让计数器加一的,我们只需要c加一,k减一即可。
  • 遍历完成后,我们对每个变量进行判断,他们如果都等于0 (除k以外,因为最后一个k没有人去减掉它,同时k的数量匹配问题可以通过a是否小于0进行判断) ,说明匹配成功,返回ans即可
class Solution:
    def minNumberOfFrogs(self, croakOfFrogs: str) -> int:
        if len(croakOfFrogs) % 5 != 0:
            return -1
        idx = {c: i for i, c in enumerate('croak')}
        cnt = [0] * 5
        ans = x = 0
        for i in map(idx.get, croakOfFrogs):
            cnt[i] += 1
            if i == 0:
                x += 1
                ans = max(ans, x)
            else:
                if cnt[i - 1] == 0:
                    return -1
                cnt[i - 1] -= 1
                if i == 4:
                    x -= 1
        return -1 if x else ans