跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

LeetCode 1419 数青蛙:基于模拟的状态机解法

数青蛙问题本质是状态机模拟。通过维护五个阶段的计数(对应 c、r、o、a、k),动态追踪每只青蛙的进度。遇到 c 时优先复用已完成叫声的青蛙,否则新增;中间字符必须依赖前一阶段有青蛙。遍历结束后若所有中间阶段计数为零,则返回最终完成次数,否则无效。

板砖工程师发布于 2026/3/21更新于 2026/6/314 浏览
LeetCode 1419 数青蛙:基于模拟的状态机解法

题目示意图

题目链接:

1419. 数青蛙 - LeetCode

问题描述

给定一个字符串 croakOfFrogs,表示若干只青蛙发出的叫声序列。每只青蛙必须按顺序发出 'c', 'r', 'o', 'a', 'k' 五个声音才能完成一次完整的叫声。如果字符串中的字符无法组成合法的叫声序列,则返回 -1;否则返回所需的最少青蛙数量。

示例图

解题思路

这本质上是一个状态机模拟问题。我们可以将青蛙的发声过程看作五个状态的流转:

  1. c: 开始叫
  2. r: 继续
  3. o: 继续
  4. a: 继续
  5. k: 结束

为了计算最少需要多少只青蛙,我们需要维护当前处于每个阶段的青蛙数量。当遇到一个新的字符时,检查是否有青蛙处于前一个阶段:

  • 遇到 'c':优先复用已经发完 'k' 的青蛙(即从 'k' 状态回到 'c' 状态),如果没有可用的,说明需要新青蛙。无论哪种情况,该青蛙现在都处于 'c' 阶段。
  • 遇到其他字符:必须存在一只青蛙正处于前驱字符的阶段。例如遇到 'r',必须有青蛙在 'c' 阶段。如果找不到,说明序列非法,直接返回 -1。

遍历结束后,所有青蛙都应该处于 'k' 阶段(即完成了叫声)。如果还有青蛙停留在中间任何阶段,说明序列不完整,返回 -1。

C++ 代码实现

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        string s = "croak";
        int n = s.size();
        
        // 记录字符映射下标关系,方便查找前驱
        unordered_map<char, int> index;
        for (int i = 0; i < n; i++) {
            index[s[i]] = i;
        }
        
        // hash[i] 表示当前处于第 i 个字符阶段的青蛙数量
        vector<int> hash(n);
        
        for (auto& ch : croakOfFrogs) {
            if (ch == 'c') {
                // 尝试复用已完成叫声的青蛙(hash[n-1])
                if (hash[n - 1] != 0) {
                    hash[n - 1]--;
                }
                // 进入 c 阶段
                hash[0]++;
            } else {
                int t = index[ch];
                // 检查前驱阶段是否有青蛙
                if (hash[t - 1] == 0) {
                    return -1;
                }
                // 从前驱阶段移动到当前阶段
                hash[t - 1]--;
                hash[t]++;
            }
        }
        
        // 检查是否所有青蛙都完成了叫声(都在 k 阶段)
        for (int i = 0; i < n - 1; i++) {
            if (hash[i] != 0) {
                return -1;
            }
        }
        
        return hash[n - 1];
    }
};

关键点总结

  • 状态复用:这是贪心策略的核心。一旦青蛙完成 'k',它就可以立即开始新的 'c',不需要额外增加计数。
  • 合法性校验:每一步转移都必须有源状态支持,否则直接判定无效。
  • 最终检查:循环结束后,除了 'k' 阶段外,其他阶段计数必须为 0,否则意味着有青蛙没叫完就中断了。

目录

  1. 问题描述
  2. 解题思路
  3. C++ 代码实现
  4. 关键点总结
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 无需第三方工具直接下载 macOS 官方镜像指南
  • N46Whisper 云端日语语音转字幕工具指南
  • Anaconda 安装与环境配置详解
  • Spring 国际化核心原理详解:4 大组件实现企业级多语言开发
  • SRC 漏洞挖掘流程及 CNVD 提交指南
  • Python 爬虫开发实战:从原理到反爬策略
  • Docker 常用命令指南
  • LLaMA Factory 大语言模型训练与微调实战指南
  • AI 编程技能(Skill)详解与 Java 方法生成实战
  • C++ STL 容器 set 与 map 使用详解
  • C++ STL 核心基础:迭代器、auto 与范围循环
  • C++ 类型转换与 IO 流实战指南
  • Java JDK 23 本地环境搭建与配置详解
  • C++ STL 进阶:set 与 map 容器使用详解
  • Stable Diffusion:AI 图像生成技术解析
  • STL stack 与 queue 底层模拟实现及算法实战
  • Python 爬虫实战:使用 requests 和正则解析前程无忧招聘信息
  • AI 提示词工程指南:从入门原理到实战模板
  • 基于 Java Web 的在线票务系统设计与实现
  • MySQL 权限管理与 C/C++ 客户端开发实战指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online