当前位置: 首页 > article >正文

6.4 模拟专题:LeetCode1419.数青蛙

1.题目链接:数青蛙 - LeetCode


2.题目描述

给定一个字符串 croakOfFrogs,表示青蛙的鸣叫声序列。每个青蛙必须按顺序发出完整的 “croak” 字符,且多只青蛙可以同时鸣叫。要求计算最少需要多少只青蛙才能完成该字符串,若无法完成则返回 -1

示例
输入:"croakcroak",输出:1(一只青蛙可重复鸣叫两次)。


3.示例分析

以输入 "crcoakroak" 为例,分析过程如下:

  1. 第一个 ‘c’ 开始,对应青蛙1。
  2. 遇到第二个 ‘c’ 时,没有已完成的青蛙(此时青蛙1未完成),需新增青蛙2。
  3. 最终青蛙1和青蛙2交替完成各自的 “croak”,最终需要2只青蛙。

4.算法思路

核心思想

通过状态哈希表跟踪每个字符的状态,确保字符顺序合法,并复用已完成鸣叫的青蛙。

具体步骤

  1. 状态定义:使用数组 hash 记录每个字符(‘c’,‘r’,‘o’,‘a’,‘k’)的出现次数。
  2. 字符处理
    • 遇到 ‘c’ 时,优先复用已完成鸣叫的青蛙(hash[4] > 0)。
    • 遇到其他字符时,必须存在前一个字符的状态(如 ‘r’ 前必须有 ‘c’)。
  3. 状态转移:每个字符处理时,减少前驱字符计数,增加当前字符计数。
  4. 结果验证:最终所有中间状态(‘c’,‘r’,‘o’,‘a’)必须清零,hash[4] 的值即为最少青蛙数。

5.边界条件与注意事项

  1. 非法顺序:若字符出现时其前驱状态不存在(如直接出现 ‘r’ 而无 ‘c’),返回 -1
  2. 未完成状态:遍历结束后若中间状态未清零,说明存在未完成的鸣叫,返回 -1
  3. 首字符处理:遇到 ‘c’ 时若无可复用青蛙,需新增计数。

6.代码实现

class Solution {
public:
    int minNumberOfFrogs(string croakOfFrogs) {
        string base = "croak";
        int n = base.size();
        vector<int> hash(n, 0); // 记录各字符的状态数
        unordered_map<char, int> index; // 字符到索引的映射
        
        for (int i = 0; i < n; ++i) 
            index[base[i]] = i;
        
        for (char ch : croakOfFrogs) {
            int idx = index[ch];
            if (ch == 'c') {
                // 复用已完成鸣叫的青蛙
                if (hash[n-1] > 0) hash[n-1]--;
                hash[0]++;
            } else {
                // 检查前驱状态是否存在
                if (hash[idx-1] == 0) return -1;
                hash[idx-1]--;
                hash[idx]++;
            }
        }
        
        // 验证中间状态是否清零
        for (int i = 0; i < n-1; ++i) {
            if (hash[i] != 0) return -1;
        }
        return hash[n-1];
    }
};

在这里插入图片描述


7.总结

本算法通过维护字符状态哈希表,实现了对青蛙鸣叫过程的精准模拟,时间复杂度为 O(n),空间复杂度 O(1)。关键在于复用青蛙和严格的状态转移检查,确保算法的效率与正确性。


http://www.kler.cn/a/610817.html

相关文章:

  • Linux网站搭建(新手必看)
  • 基于k3s部署Nginx、MySQL、PHP和Redis的详细教程
  • 深度学习(practice) Note.2
  • idea 没有 add framework support(添加框架支持)选项
  • matplotlib——南丁格尔玫瑰
  • 2.Excel :快速填充和拆分重组
  • 自动驾驶VLA模型技术解析与模型设计
  • Kotlin的语言特性及使用场景
  • DDD领域驱动设计详解-Java/Go/JS/Python语言实现
  • 一周掌握Flutter开发--7、包管理
  • 【自学笔记】ELK基础知识点总览-持续更新
  • 2、pytest核心功能(进阶用法)
  • QT Quick(C++)跨平台应用程序项目实战教程 4 — QML基本使用方法
  • fastapi下载图片
  • 大语言模型-2.2/3-主流模型架构与新型架构
  • C#基础学习(五)函数中的ref和out
  • Linux系统管理与编程11: DHCP中继服务部署
  • OpenGL ES 2.0与OpenGL ES 3.1的区别
  • 深度剖析 Spring 源码 性能优化:核心原理与最佳实践
  • 啸叫抑制(AFS)从算法仿真到工程源码实现-第八节-系统搭建