爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      一文详解“模拟算法“在算法中的应用

      首页 知识中心 数据库 文章详情页

      一文详解“模拟算法“在算法中的应用

      2025-02-12 09:25:49 阅读次数:14

      字符,字符串,青蛙

      介绍

      模拟算法的核心与其名一样,重在模拟,主要是根据题目的要求,进行无脑的暴力模拟去实现。这类题目还是比较简单的,相较于那些没有思路的题目来说。主要考察的是我们的编码能力。

      1576.替换所有的问号

      题目:

      给你一个仅包含小写英文字母和 '?' 字符的字符串 s,请你将所有的 '?' 转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。

      注意:你 不能 修改非 '?' 字符。

      题目测试用例保证 除 '?' 字符 之外,不存在连续重复的字符。

      在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。

      示例 1:

      输入:s = "?zs"
      输出:"azs"
      解释:该示例共有 25 种解决方案,从 "azs" 到 "yzs" 都是符合题目要求的。只有 "z" 是无效的修改,因为字符串 "zzs" 中有连续重复的两个 'z' 。

      示例 2:

      输入:s = "ubv?w"
      输出:"ubvaw"
      解释:该示例共有 24 种解决方案,只有替换成 "v" 和 "w" 不符合题目要求。因为 "ubvvw" 和 "ubvww" 都包含连续重复的字符。
      
      

      提示:

      • 1 <= s.length <= 100

      • s 仅包含小写英文字母和 '?' 字符

      思路:题目是让我们在一堆小写字母和"?"中,将"?"给替换成小写字母,且相邻的小写字母之间不能出现重复,但是不相邻的小写字母之间可以出现重复。

      代码实现:

      class Solution {
          public String modifyString(String s) {
              int n = s.length();
              if (n == 1) { // 排除特殊情况
                  char ch = s.charAt(0);
                  return ch == '?' ? "a" : s;
              }
              StringBuilder sb = new StringBuilder();
              char[] ans = s.toCharArray();
              for (int i = 0; i < n; i++) {
                  char ch = s.charAt(i);
                  if (ch == '?') {
                      if (i == 0) { // 没有前缀字符
                          // 拿到后缀字符
                          char r = s.charAt(1);
                          for (char j = 'a'; j <= 'z'; j++) {
                              if (j != r) {
                                  sb.append(j);
                                  ans[i] = j;
                                  break;
                              }
                          }
                      } else if (i == n-1) { // 没有后缀字符
                          // 拿到前缀字符(修改后的)
                          char l = ans[n-2];
                          for (char j = 'a'; j <= 'z'; j++) {
                              if (j != l) {
                                  sb.append(j);
                                  ans[i] = j;
                                  break;
                              }
                          }
                      } else {
                          // 拿到前缀和后缀
                          char l = ans[i-1]; // 修改后的
                          char r = s.charAt(i+1);
                          for (char j = 'a'; j <= 'z'; j++) {
                              if (j != l && j != r) {
                                  sb.append(j);
                                  ans[i] = j;
                                  break;
                              }
                          }
                      }
                  } else {
                      sb.append(ch);
                      ans[i] = ch;
                  }
              }
              return sb.toString();
          }
      }

      这里我们在修改的同时,还得记录,因为字符串中没有修改过的,而我们是要在修改的基础上再进行判断修改的。因此我们便不采用 StringBuilder 的方式,而是直接在数组上进行修改即可。

      class Solution {
          public String modifyString(String s) {
              char[] ans = s.toCharArray();
              int n = ans.length;
              for (int i = 0; i < n; i++) {
                  char ch = ans[i];
                  if (ch == '?') { // 需要修改
                      for (char j = 'a'; j <= 'z'; j++) { // 找到可以替换的
                          // 前面的字符 和 后面的字符都满足即可
                          if ((i == 0 || j != ans[i-1]) && (i == n-1 || j != ans[i+1])) {
                              ans[i] = j;
                              break;
                          }
                      }
                  }
              }
              return new String(ans);
          }
      }

      495.提莫攻击

      题目:

      在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。

      当提莫攻击艾希,艾希的中毒状态正好持续 duration 秒。

      正式地讲,提莫在 t 发起攻击意味着艾希在时间区间 [t, t + duration - 1](含 t 和 t + duration - 1)处于中毒状态。如果提莫在中毒影响结束 前 再次攻击,中毒状态计时器将会 重置 ,在新的攻击之后,中毒影响将会在 duration 秒后结束。

      给你一个 非递减 的整数数组 timeSeries ,其中 timeSeries[i] 表示提莫在 timeSeries[i] 秒时对艾希发起攻击,以及一个表示中毒持续时间的整数 duration 。

      返回艾希处于中毒状态的 总 秒数。

       

      示例 1:

      输入:timeSeries = [1,4], duration = 2
      输出:4
      解释:提莫攻击对艾希的影响如下:
      - 第 1 秒,提莫攻击艾希并使其立即中毒。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。
      - 第 4 秒,提莫再次攻击艾希,艾希中毒状态又持续 2 秒,即第 4 秒和第 5 秒。
      艾希在第 1、2、4、5 秒处于中毒状态,所以总中毒秒数是 4 。

      示例 2:

      输入:timeSeries = [1,2], duration = 2
      输出:3
      解释:提莫攻击对艾希的影响如下:
      - 第 1 秒,提莫攻击艾希并使其立即中毒。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。
      - 第 2 秒,提莫再次攻击艾希,并重置中毒计时器,艾希中毒状态需要持续 2 秒,即第 2 秒和第 3 秒。
      艾希在第 1、2、3 秒处于中毒状态,所以总中毒秒数是 3 。
      
      

      提示:

      • 1 <= timeSeries.length <= 104
      • 0 <= timeSeries[i], duration <= 107
      • timeSeries 按 非递减 顺序排列

      思路:题目说了这么多,其实就是表达这样一个意思:有一个表示初始时间的数组,再来一个表示持续时长的数字,让我们求总共有多少秒。数组中的值有两类:一类是在初始时间到结束时间(加上持续时长)之内;还有一类是初始时间到结束时间之外。第二类,我们直接加上持续时间即可,而对于第一类我们要计算其有效时长:第二个初始时间 - 第一类初始时间。

      代码实现:

      class Solution {
          public int findPoisonedDuration1(int[] timeSeries, int duration) {
              int sum = 0;
              int n = timeSeries.length;
              for (int i = 0; i < n; i++) {
                  // 判断中毒的时间是否是默认时长
                  if (i+1 < n && timeSeries[i+1] < timeSeries[i]+duration) {
                      sum += (timeSeries[i+1] - timeSeries[i]);
                  } else {
                      sum += duration;
                  }
              }
              return sum;
          }
      }

      6.Z字形变换

      题目:

      将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

      比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

      P   A   H   N
      A P L S I I G
      Y   I   R

      之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。

      请你实现这个将字符串进行指定行数变换的函数:

      string convert(string s, int numRows);
      

      示例 1:

      输入:s = "PAYPALISHIRING", numRows = 3
      输出:"PAHNAPLSIIGYIR"
      
      示例 2:
      输入:s = "PAYPALISHIRING", numRows = 4
      输出:"PINALSIGYAHRPI"
      解释:
      P     I    N
      A   L S  I G
      Y A   H R
      P     I
      

      示例 3:

      输入:s = "A", numRows = 1
      输出:"A"
      
      

      提示:

      • 1 <= s.length <= 1000
      • s 由英文字母(小写和大写)、',' 和 '.' 组成
      • 1 <= numRows <= 1000

      思路: 题目的意思是让我们把给的字符串,按照Z字形排列后,重新从上到下拼接出一个新的字符串。首先很容易想到的一个思路,就是直接用一个数组去接收字符串,然后再去遍历数组。

      一文详解“模拟算法“在算法中的应用

      代码实现:

      class Solution {
          public String convert(String s, int numRows) {
              // 当只有一行或者只有一列时,直接返回结果即可
              if (numRows == 1 || numRows >= s.length()) {
                  return s;
              }
              // 1、做准备工作
              char[] str = s.toCharArray();
              char[][] ch = new char[numRows][1000];
              // Arrays.fill(ch, '*'); 这里不能直接去填充,fill方法只能填充一维数组
              // 如果要填充二维数组,只能遍历拿出一维数组,再去赋值了
              // 2、遍历字符串填充数组
              int index = 0;
              int len = str.length;
              int i = 0;
              int j = 0;
              while (index < len) {
                  while (i < numRows-1) {
                      if (index < len) {
                          ch[i++][j] = str[index++];
                      } else {
                          break;
                      }
                  }
                  while (i > 0) {
                      if (index < len) {
                          ch[i--][j++] = str[index++];
                      } else {
                          break;
                      }
                  }
              }
              // 3、从数组中拿值,拼凑字符串
              StringBuilder sb = new StringBuilder();
              for (i = 0; i < numRows; i++) {
                  for (j = 0; j < 1000; j++) {
                      // '\u0000' 这个是字符数组的默认值
                      if (ch[i][j] != '\u0000') {
                          sb.append(ch[i][j]);
                      }
                  }
              }
              return sb.toString();
          }
      }

      上面的方法更容易想到,也是比较简单的方法,除此之外还有找规律的方法。

      一文详解“模拟算法“在算法中的应用

      代码实现:

      class Solution {
          public String convert(String s, int numRows) {
              // 当只有一行或者只有一列时,直接返回结果即可
              if (numRows == 1 || numRows > s.length()) {
                  return s;
              }
              StringBuilder sb = new StringBuilder();
              int d = 2 * numRows - 2;
              int len = s.length();
              // 按照从上到下的顺序直接来计算
              // 第一行
              for (int i = 0; i < len; i += d) {
                  sb.append(s.charAt(i));
              }
              // 中间行
              for (int k = 1; k < numRows-1; k++) { // k是行数
                  // i 是前一个,j 是后一个,只要两者有一个是小于len的,就需要进入循环
                  for (int i = k, j = d-k; i < len || j < len; i += d, j += d) {
                      // 这里的顺序只能是先i后j
                      if (i < len) {
                          sb.append(s.charAt(i));
                      }
                      if (j < len) {
                          sb.append(s.charAt(j));
                      }
                  }
              }
              // 最后一行
              for (int i = numRows-1; i < len; i += d) {
                  sb.append(s.charAt(i));
              }
              return sb.toString();
          }
      }

      注意:在 Java中, 当声明一个基本数据类型的数组时,如果没有显式地为数组元素赋值,数组元素会被自动初始化为该数据类型的默认值。对于char类型的数组,其默认值是‘\u0000’,这是一个空字符,其Unicode 值为 0。而不是' ',这是空格字符,Unicode值是32。我们认为的空字符应该是 '',但是这种写法在Java中时符合语法规范的。Java中,字符的定义是 必须用单引号括起来且单引号内必须有且仅有一个字符。

      38.外观数列

      题目:

      「外观数列」是一个数位字符串序列,由递归公式定义:

      • countAndSay(1) = "1"
      • countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。

      行程长度编码(RLE)是一种字符串压缩方法,其工作原理是通过将连续相同字符(重复两次或更多次)替换为字符重复次数(运行长度)和字符的串联。例如,要压缩字符串 "3322251" ,我们将 "33" 用 "23" 替换,将 "222" 用 "32" 替换,将 "5" 用 "15" 替换并将 "1" 用 "11" 替换。因此压缩后字符串变为 "23321511"。

      给定一个整数 n ,返回 外观数列 的第 n 个元素。

      示例 1:

      输入:n = 4

      输出:"1211"

      解释:

      countAndSay(1) = "1"

      countAndSay(2) = "1" 的行程长度编码 = "11"

      countAndSay(3) = "11" 的行程长度编码 = "21"

      countAndSay(4) = "21" 的行程长度编码 = "1211"

      示例 2:

      输入:n = 1

      输出:"1"

      解释:

      这是基本情况。

       

      提示:

      • 1 <= n <= 30

      思路: 如果不仔细阅读,这个题目的意思还是有点让人捉摸不透。根据示例的解释,我们可以明白题目给了一个参数n,让我们求n在经过函数计算之后的字符串是啥,第一项是"1",这是固定的,后面的项就是根据前面一项的"读"出来的。

      countAndSay(1) = "1" ——> 这是固定的。

      countAndSay(2) = "1" 的行程长度编码 = "11" ——> 读前一项,一个1,即 11。

      countAndSay(3) = "11" 的行程长度编码 = "21" ——> 读前一项,俩个个1,即 21。

      countAndSay(4) = "21" 的行程长度编码 = "1211"——> 读前一项,一个2,一个1,即1211。

      读的操作的过程:

      一文详解“模拟算法“在算法中的应用

      因为 countAndSay(n) 是 countAndSay(n-1) 的行程长度编码,所以在计算第n项时,先得计算第n-1项,计算第n-1项,又得先计算第n-2项,....,直至计算到第1项。这个过程其实就是递归的。 

      代码实现:

      class Solution {
          public String countAndSay(int n) {
              // 因为 countAndSay(n) 是 countAndSay(n-1) 的行程长度编码
              // 行程长度编码就是在"读"数据
              // 相当于求第n项,就是在"读"第n-1项
              
              if (n == 1) {
                  return "1";
              }
              // 先拿到第n-1项的数据
              char[] ch = countAndSay(n-1).toCharArray();
              // 开始"读"数据:使用双指针分组数据
              StringBuilder sb = new StringBuilder();
              for (int left = 0, right = 0; right < ch.length;) {
                  // 让 left 与 right 到达数组的两个边界
                  // 注意:处理数组越界
                  while (right < ch.length && ch[left] == ch[right]) {
                      right++;
                  }
                  // 开始"读"操作
                  sb.append(right-left);
                  sb.append(ch[left]);
                  // 开始新的分组
                  left = right;
              }
              return sb.toString();
          }
      }

      1419. 数青蛙

      题目:

      给你一个字符串 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 <= 105
      • 字符串中的字符只有 'c', 'r', 'o', 'a' 或者 'k'

      思路:题目是让我们遍历字符串,找到叫声数量最少的青蛙数,且青蛙在叫的过程中,严格遵守 c r o a k 的顺序。 即当我们遍历到某个叫声字符时,就可以去看看当前的前一个字符是否有青蛙已经叫过了。如果前一个字符没有青蛙叫过,那么这个叫声肯定不是青蛙的。如果前一个字符青蛙叫过了,那么处于当前字符的青蛙数++,处于前一个字符的青蛙数--。但是有个特殊的情况,我们得注意,当青蛙刚开始叫 c 这个字符时,既可以是前面已经叫完了的青蛙叫的,也可能是新的青蛙叫的,怎么判断呢?题目这里说的是最少数量,那么去判断处于 k字符的青蛙数量是否为0(因为当青蛙叫完之后,肯定是出于k字符的位置的),如果为0,则是有新的青蛙在叫,反之,则是剩余的青蛙在叫,那只需将 k字符的青蛙数--,c字符的青蛙数++。

      总的来说,分两种情况,c字符,就是看是否有新的青蛙,其余字符就是看是否有处于前一个字符的青蛙。

      代码实现:

      class Solution {
          public int minNumberOfFrogs(String croakOfFrogs) {
              // 存储青蛙的叫声与此时的青蛙数量
              HashMap<Character, Integer> hash = new HashMap<>();
              hash.put('c', 0);
              hash.put('r', 0);
              hash.put('o', 0);
              hash.put('a', 0);
              hash.put('k', 0);
              // 遍历叫声,数青蛙
              char[] str = croakOfFrogs.toCharArray();
              int count = 0;
              for (int i = 0; i < str.length; i++) {
                  char ch = str[i];
                  // 判断当前字符的情况:
                  // 1、起始字符,就看结束字符的数量;
                  // 2、如果是中间字符,就看前一个字符的数量
                  if (ch == 'c') {
                      if (hash.getOrDefault('k', 0) != 0) { // 有空闲的青蛙
                          // 当前叫声的青蛙数++,空闲青蛙数--
                          hash.replace('c', hash.getOrDefault('c', 0)+1);
                          hash.replace('k', hash.get('k')-1);
                      } else { // 没有空闲的青蛙,只能是新来了青蛙
                          hash.put('c', hash.getOrDefault('c', 0)+1);
                          count++;
                      }
                  } else if (ch == 'r') {
                      // 判断是否有前一个字符
                      if (hash.getOrDefault('c', 0) != 0) {
                          hash.replace('c', hash.get('c')-1);
                          hash.replace('r', hash.getOrDefault('r', 0)+1);
                      } else {
                          return -1;
                      }
                  } else if (ch == 'o') {
                      if (hash.getOrDefault('r', 0) != 0) {
                          hash.replace('r', hash.get('r')-1);
                          hash.replace('o', hash.getOrDefault('o', 0)+1);
                      } else {
                          return -1;
                      }
                  } else if (ch == 'a') {
                      if (hash.getOrDefault('o', 0) != 0) {
                          hash.replace('o', hash.get('o')-1);
                          hash.replace('a', hash.getOrDefault('a', 0)+1);
                      } else {
                          return -1;
                      }
                  } else if (ch == 'k') {
                      if (hash.getOrDefault('a', 0) != 0) {
                          hash.replace('a', hash.get('a')-1);
                          hash.replace('k', hash.getOrDefault('k', 0)+1);
                      } else {
                          return -1;
                      }
                  } else { // 不是青蛙的叫声
                      return -1;
                  }
              }
              // 判断哈希表中是否还有剩余青蛙处于"叫"的状态
              // 这是通过测试用例排除出来的,为了偷懒只写了一部分,正常要把前面的叫声全部判断一遍
              if (hash.getOrDefault('a', 0) != 0 || hash.getOrDefault('c', 0) != 0) {
                  return -1;
              }
              return count;
          }
      }

      上面的代码是根据思路直接写出来的,有点冗长,我们可以去尝试优化。

      优化的地方:主要是多个if-else给去掉。而多个if-else存在的原因是我们不知道当前字符对应的青蛙数量。

      一文详解“模拟算法“在算法中的应用

      class Solution {
          public int minNumberOfFrogs(String croakOfFrogs) {
              // 使用数组来记录当前叫声位置的青蛙数
              int[] count = new int[5];
              // 使用哈希表来记录索引
              HashMap<Character, Integer> hash = new HashMap<>();
              for (int i = 0; i < 5; i++) {
                  hash.put("croak".charAt(i), i);
              }
              // 遍历叫声字符串
              int len = croakOfFrogs.length();
              char[] str = croakOfFrogs.toCharArray();
              for (int i = 0; i < len; i++) {
                  // 判断当前字符是c字符,还是其他字符
                  // 题目说了,不会出现其他无关字符,因此我们可以不用判断
                  char ch = str[i];
                  if (ch == 'c') {
                      // 判断是否是剩余青蛙在叫
                      if (count[hash.get('k')] != 0) {
                          count[hash.get('k')]--;
                      }
                      count[hash.get('c')]++;
                  } else {
                      // 判断是否有处于前一个叫声的青蛙
                      if (count[hash.get(ch)-1] == 0) { // 注意这里的写法
                          return -1;
                      }
                      // 前一个叫声的青蛙数--,当前叫声的青蛙数++
                      count[hash.get(ch)-1]--;
                      count[hash.get(ch)]++;
                  }
              }
              // 判断剩余叫声中是否有青蛙数,如果有,则不是青蛙叫声
              for (int i = 0; i < 5; i++) {
                  if (count[i] != 0) {
                      // 返回处于k位置的青蛙数即可
                      return i == 4 ? count[i] : -1;
                  }
              }
              return -1; // 这里只是为了通过编译
          }
      }

      好啦!本期  一文详解“模拟算法“ 的学习之旅 就到此结束啦!我们下一期再一起学习吧!

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/2301_80854132/article/details/143193671,作者:我要学编程(ಥ_ಥ),版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:数据结构-二叉树中的递归

      下一篇:数据结构-排序课后题

      相关文章

      2025-05-19 09:04:14

      C语言字符函数和字符串函数--(超全超详细)

      C语言字符函数和字符串函数--(超全超详细)

      2025-05-19 09:04:14
      函数 , 字符 , 字符串
      2025-05-14 10:33:31

      计算机小白的成长历程——习题演练(函数篇)

      计算机小白的成长历程——习题演练(函数篇)

      2025-05-14 10:33:31
      函数 , 字符串 , 数组 , 知识点 , 编写 , 迭代 , 递归
      2025-05-14 10:33:16

      30天拿下Rust之切片

      在Rust中,切片是一种非常重要的引用类型。它允许你安全地引用一段连续内存中的数据,而不需要拥有这些数据的所有权。切片不包含分配的内存空间,它仅仅是一个指向数据开始位置和长度的数据结构。

      2025-05-14 10:33:16
      amp , end , 切片 , 字符串 , 引用 , 索引 , 迭代
      2025-05-14 10:33:16

      30天拿下Python之使用Json

      Json的英文全称为JavaScript Object Notation,中文为JavaScript对象表示法,是一种存储和交换文本信息的语法,类似XML。Json作为轻量级的文本数据交换格式,比XML更小、更快,更易解析,也更易于阅读和编写。

      2025-05-14 10:33:16
      json , Json , Python , 字符串 , 对象 , 序列化 , 转换
      2025-05-14 10:33:16

      30天拿下Rust之字符串

      在Rust中,字符串是一种非常重要的数据类型,用于处理文本数据。Rust的字符串是以UTF-8编码的字节序列,主要有两种类型:&str和String。其中,&str是一个对字符数据的不可变引用,更像是对现有字符串数据的“视图”,而String则是一个独立、可变更的字符串实体。

      2025-05-14 10:33:16
      amp , Rust , str , String , 使用 , 字符串 , 方法
      2025-05-14 10:03:13

      超级好用的C++实用库之Base64编解码

      Base64是一种编码方式,用于将二进制数据转换为可打印的ASCII字符。这种编码方式常用于在HTTP协议等应用中传输二进制数据,比如:图片、音频、视频等。

      2025-05-14 10:03:13
      Base64 , 字符串 , 数据 , 编码 , 长度
      2025-05-14 10:02:58

      超级好用的C++实用库之字符编码转换

      字符编码转换是指将文本数据从一种字符集编码格式转换为另一种字符集编码格式的过程。

      2025-05-14 10:02:58
      buffer , Unicode , 字符 , 字符集 , 编码
      2025-05-14 09:51:15

      java String 去掉特殊字符之前的内容

      为了去除字符串中某个特殊字符之前(包括该特殊字符本身)的所有内容,我们可以使用Java中的String类的substring和indexOf方法。

      2025-05-14 09:51:15
      字符 , 字符串 , 正则表达式 , 示例
      2025-05-13 09:53:23

      java中判断String类型为空和null的方法

      在Java中,判断一个String类型的变量是否为空(即长度为0)或者为null,通常需要使用两个条件语句来进行检查。这是因为null表示变量没有引用任何对象,而空字符串("")表示变量引用了一个没有内容的字符串对象。

      2025-05-13 09:53:23
      null , String , 为空 , 字符串 , 方法 , 示例 , 默认值
      2025-05-13 09:53:13

      计算机初级选手的成长历程——青蛙跳台阶问题详解

      计算机初级选手的成长历程——青蛙跳台阶问题详解

      2025-05-13 09:53:13
      函数 , 方式 , 递归 , 青蛙
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5238135

      查看更多

      最新文章

      30天拿下Rust之字符串

      2025-05-14 10:33:16

      30天拿下Rust之切片

      2025-05-14 10:33:16

      java String 去掉特殊字符之前的内容

      2025-05-14 09:51:15

      java中判断String类型为空和null的方法

      2025-05-13 09:53:23

      java实现3. 无重复字符的最长子串

      2025-05-13 09:50:17

      java实现-13. 罗马数字转整数

      2025-05-13 09:50:17

      查看更多

      热门文章

      groovy replace字符串替换

      2023-03-24 10:30:38

      oracle字符串处理函数(部分)

      2022-12-29 09:29:46

      python学习——【第一弹】

      2023-02-28 07:38:41

      python字符串str与byte字节相等==判断

      2023-04-11 10:46:53

      切片用法——去空格

      2024-07-01 01:30:59

      python将字符串转为字典(将str类型还原为dict字典类型)

      2023-04-17 10:54:33

      查看更多

      热门标签

      数据库 mysql 字符串 数据结构 MySQL 算法 redis oracle java sql python 数据 索引 SQL 查询
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      字典的相关应用

      基础—常用数据结构:列表、元祖、集合、字典、函数等(爬虫及数据可视化)

      387. 字符串中的第一个唯一字符.py-----leetcode刷题(python解题)

      1223. 数字字符统计

      #私藏项目实操分享#【Redis集群原理专题】分析一下相关的Redis服务分片技术和Hash Tag

      字符串压缩与解压(JAVA)

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号