算法思想之模拟
欢迎拜访:雾里看山-CSDN博客
本篇主题:算法思想之模拟
发布时间:2025.4.14
隶属专栏:算法

目录
- 算法介绍
- 核心特点
- 常见问题
- 优化方向
- 例题
- 替换所有的问号
- 题目链接
- 题目描述
- 算法思路
- 代码实现
- 提莫攻击
- 题目链接
- 题目描述
- 算法思路
- 代码实现
- Z 字形变换
- 题目链接
- 题目描述
- 算法思路
- 代码实现
- 外观数列
- 题目链接
- 题目描述
- 算法思路
- 代码实现
- 数青蛙
- 题目链接
- 题目描述
- 算法思路
- 代码实现
算法介绍
模拟算法(Simulation Algorithm)是一种通过直接按照问题描述的步骤进行程序化实现的算法,强调对现实过程或逻辑规则的忠实还原。其核心思想是 “无需复杂优化,严格按规则执行”,常用于解决流程明确但实现细节繁琐的问题。
核心特点
- 流程驱动:严格遵循问题描述的操作步骤。
- 细节密集:需要处理大量边界条件和状态变化。
- 直观性强:代码结构常与问题描述高度对应。
常见问题
- 边界错误:数组越界、循环终止条件错误
- 状态遗漏:未正确更新中间状态变量
- 性能陷阱:大数量级时超时(需改用数学方法)
优化方向
- 高频状态查询:使用哈希表记录关键状态
- 大量重复计算:预计算并缓存结果
- 空间浪费:压缩存储(如位运算)
例题
替换所有的问号
题目链接
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 <= 100s仅包含小写英文字母和'?'字符
算法思路
纯模拟。从前往后遍历整个字符串,找到问号之后,就用 a ~ z 的每一个字符去尝试替换即可。
代码实现
class Solution {
public:string modifyString(string s) {int n = s.size();for(int i = 0; i < n; i++){if(s[i] == '?'){for(char c = 'a'; c <= 'z'; c++){if((i==0 || s[i-1] != c) && (i == n-1 || s[i+1] != c)){s[i] = c;break;}}}}return s;}
};

提莫攻击
题目链接
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 <= 1040 <= timeSeries[i], duration <= 107timeSeries按 非递减 顺序排列
算法思路
模拟 + 分情况讨论。
计算相邻两个时间点的差值:
- 如果差值大于等于中毒时间,说明上次中毒可以持续
duration秒; - 如果差值小于中毒时间,那么上次的中毒只能持续两者的差值。
代码实现
class Solution {
public:int findPoisonedDuration(vector<int>& timeSeries, int duration) {int n = timeSeries.size();int ret = 0;for(int i = 1; i < n; i++){if(timeSeries[i]-timeSeries[i-1] < duration)ret+=timeSeries[i]-timeSeries[i-1];elseret+=duration;}ret+=duration;return ret;}
};

Z 字形变换
题目链接
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 <= 1000s由英文字母(小写和大写)、','和'.'组成1 <= numRows <= 1000
算法思路
找规律,用 row 代替行数,row = 4 时画出的 N 字形如下:
0 2row - 2 4row - 4
1 2row - 3 2row - 1 4row - 5 4row - 3
2 2row-4 2row 4row - 6 4row - 2
3 2row + 1 4row - 1
不难发现,数据是以 2row - 2 为一个周期进行规律变换的。将所有数替换成用周期来表示的变量:
第⼀行的数是:0, 2row - 2, 4row - 4;
第⼆行的数是:1, (2row - 2) - 1, (2row - 2) + 1, (4row - 4) - 1, (4row - 4) + 1;
第三行的数是:2, (2row - 2) - 2, (2row - 2) + 2, (4row - 4) - 2, (4row - 4) + 2;
第四行的数是:3, (2row - 2) + 3, (4row - 4) + 3。
可以观察到,第一行、第四行为差为 2row - 2 的等差数列;第二行、第三行除了第一个数取值为行数,每组下标为(2n - 1, 2n)的数围绕(2row - 2)的倍数左右取值。
以此规律,我们可以写出迭代算法。
代码实现
class Solution {
public:string convert(string s, int numRows) {if(numRows == 1)return s;int d = 2*numRows -2, n = s.size();string ret;for(int i = 0; i < n; i+=d)//处理第一行ret+=s[i];for(int k = 1; k < numRows-1; k++)for(int i = k,j = d-k; i < n || j < n; i += d, j += d){if(i<n)ret+=s[i];if(j<n)ret+=s[j];}for(int i = numRows-1; i < n; i += d)ret += s[i];return ret;}
};

外观数列
题目链接
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进阶:你能迭代解决该问题吗?
算法思路
所谓外观数列,其实只是依次统计字符串中连续且相同的字符的个数。依照题意,依次模拟即可。
代码实现
class Solution {
public:string countAndSay(int n) {string s = "1";while(--n){string ret;int left = 0, right = 0, sum = s.size();while(right < sum){while(right<sum &&s[right] == s[left])right++;ret+=to_string(right-left);ret+=s[left];left = right;}s = ret;}return s;}
};

数青蛙
题目链接
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'
算法思路
模拟青蛙的叫声。
- 当遇到
'r''o''a''k'这四个字符的时候,我们要去看看每一个字符对应的前驱字符,有没有青蛙叫出来。如果有青蛙叫出来,那就让这个青蛙接下来喊出来这个字符;如果没有,直接返回-1; - 当遇到
'c'这个字符的时候,我们去看看'k'这个字符有没有青蛙叫出来。如果有,就让这个青蛙继续去喊'c'这个字符;如果没有的话,就重新搞一个青蛙。
代码实现
class Solution {
public:int minNumberOfFrogs(string croakOfFrogs) {string t = "croak";int n = t.size();vector<int> hash(n);// 用数组模拟hash表unordered_map<char, int> index;//字符和数组下标的映射for(int i = 0; i < n; i++)index[t[i]] = i;for(auto ch : croakOfFrogs){if(ch == 'c'){if(hash[n-1] != 0)hash[n-1]--;hash[0]++;}else{int i = index[ch];if(hash[i-1] == 0)return -1;hash[i-1]--;hash[i]++;}}for(int i = 0; i < n-1; i++){if(hash[i] != 0)return -1;}return hash[n-1];}
};

⚠️ 写在最后:以上内容是我在学习以后得一些总结和概括,如有错误或者需要补充的地方欢迎各位大佬评论或者私信我交流!!!
相关文章:
算法思想之模拟
欢迎拜访:雾里看山-CSDN博客 本篇主题:算法思想之模拟 发布时间:2025.4.14 隶属专栏:算法 目录 算法介绍核心特点常见问题优化方向 例题替换所有的问号题目链接题目描述算法思路代码实现 提莫攻击题目链接题目描述算法思路代码实现…...
测试基础笔记第四天(html)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 html介绍1. 介绍2.骨架标签3.常用标签标题标签段落标签超链接标签图片标签换行和空格标签布局标签input标签(变形金刚)form标签列表标签 htm…...
WPF 中的元素继承层次结构 ,以下是对图中内容的详细说明:
顶层基类 DispatcherObject:处于继承体系最顶端,是一个抽象类。它为 WPF 元素提供了与 Dispatcher(调度器)交互的能力,Dispatcher 负责管理线程间的消息传递,确保 UI 操作在正确的线程(通常是 …...
十九、UDP编程和IO多路复用
1、UDP编程 服务端: #include<stdio.h> #include <arpa/inet.h> #include<stdlib.h> #include<string.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <pthread.h> #include &l…...
DeepSeek使用001:Word中配置DeepSeek AI的V3和R1模型
文章目录 Word中配置DeepSeek大模型1、勾选开发工具2、信任中心设置3、添加DeepSeek-V3模型4、获取API KEY5、添加DeepSeek-R1模型6、新建组7、测试使用 Word中配置DeepSeek大模型 1、勾选开发工具 打开【选项】 选择【自定义功能区】 2、信任中心设置 打开【信任中心】&…...
linux tracepoint系列宏定义(TRACE_EVENT,DEFINE_TRACE等)展开过程分析之三 define_trace.h头文件
在linux tracepoint系列宏定义(TRACE_EVENT,DEFINE_TRACE等)展开过程分析之二 文章中,我们知道trace-events-sample.h 文件在包含了tracepoint.h后第一次对TRACE_EVENT(...)等系列宏定义进行了展开,主要是构建tracepoint 调用钩子函数,注册/注销函数。展开的第二阶段…...
TDengine 与其他时序数据库对比:InfluxDB/TimescaleDB 选型指南(二)
四、应用场景分析 (一)TDengine 适用场景 TDengine 适用于对写入性能和存储效率要求极高的物联网设备数据采集场景。在一个拥有数百万个传感器的智能工厂中,每个传感器每秒都会产生多条数据,TDengine 能够高效地处理这些高并发的…...
华为OD机试真题——攀登者2(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式! 华为OD机试真题《攀登者2》: 目录 题目名称:攀登者2…...
Windows卸载重装Docker
卸载 删除C:\Program Files\Docker ,如果更改了路径的就找到相关位置进行删除 删除 C:\Users\<用户名>\.docker 清理注册表,不然重装会报错 Exising installation is up to date 按下WindowR唤起命令输入界面,输入regedit打开注…...
JVM 为什么需要即时编译器?
JVM之所以需要即时编译器 (JIT Compiler),是为了提高 Java 程序的执行性能,弥补纯解释器执行的不足。 我们可以从以下几个角度来分析一下这个问题: 1. 解释器的性能瓶颈: 逐条解释的开销: 解释器需要逐条读取 Java 字节码指令,并…...
双目视觉中矩阵等参数说明及矫正
以下是标定文件中各个参数的详细解释: 1. 图像尺寸 (imageSize) 参数值: [1280, 1024]含义: 相机的图像分辨率,宽度为1280像素,高度为1024像素。 2. 相机内参矩阵 (leftCameraMatrix / rightCameraMatrix) 结构: yaml data: [fx, 0, cx, 0,…...
Android Compose 框架的列表与集合模块之滑动删除与拖拽深入分析(四十八)
Android Compose 框架的列表与集合模块之滑动删除与拖拽深入分析 一、引言 本人掘金号,欢迎点击关注:https://juejin.cn/user/4406498335701950 1.1 Android Compose 简介 在 Android 开发领域,界面的交互性和用户体验至关重要。传统的 A…...
一、LLM 大语言模型初窥:起源、概念与核心原理
一、初识大模型 1.1 人工智能演进与大模型兴起:从A11.0到A12.0的变迁 AI 1.0时代(2012-2022年) 感知智能的突破:以卷积神经网络(CNN)为核心,AI在图像识别、语音处理等感知任务中超越人类水平。例如&#…...
PyTorch核心函数详解:gather与where的实战指南
PyTorch中的torch.gather和torch.where是处理张量数据的关键工具,前者实现基于索引的灵活数据提取,后者完成条件筛选与动态生成。本文通过典型应用场景和代码演示,深入解析两者的工作原理及使用技巧,帮助开发者提升数据处理的灵活…...
《Operating System Concepts》阅读笔记:p636-p666
《Operating System Concepts》学习第 58 天,p636-p666 总结,总计 31 页。 一、技术总结 1.system and network threats (1)attack network traffic (2)denial of service (3)port scanning 2.symmetric/asymmetric encryption algorithm (1)symm…...
Go:接口
接口既约定 Go 语言中接口是抽象类型 ,与具体类型不同 ,不暴露数据布局、内部结构及基本操作 ,仅提供一些方法 ,拿到接口类型的值 ,只能知道它能做什么 ,即提供了哪些方法 。 func Fprintf(w io.Writer, …...
ESP32+Arduino入门(三):连接WIFI获取当前时间
ESP32内置了WIFI模块连接WIFI非常简单方便。 代码如下: #include <WiFi.h>const char* ssid "WIFI名称"; const char* password "WIFI密码";void setup() {Serial.begin(115200);WiFi.begin(ssid,password);while(WiFi.status() ! WL…...
FastAPI用户认证系统开发指南:从零构建安全API
前言 在现代Web应用开发中,用户认证系统是必不可少的功能。本文将带你使用FastAPI框架构建一个完整的用户认证系统,包含注册、登录、信息更新和删除等功能。我们将采用JWT(JSON Web Token)进行身份验证,并使用SQLite作…...
CSS高度坍塌?如何解决?
一、什么是高度坍塌? 高度坍塌(Collapsing Margins)是指当父元素没有设置边框(border)、内边距(padding)、内容(content)或清除浮动时,其子元素的 margin 会…...
【数据结构】之散列
一、定义与基本术语 (一)、定义 散列(Hash)是一种将键(key)通过散列函数映射到一个固定大小的数组中的技术,因为键值对的映射关系,散列表可以实现快速的插入、删除和查找操作。在这…...
空地机器人在复杂动态环境下,如何高效自主导航?
随着空陆两栖机器人(AGR)在应急救援和城市巡检等领域的应用范围不断扩大,其在复杂动态环境中实现自主导航的挑战也日益凸显。对此香港大学王俊铭基于阿木实验室P600无人机平台自主搭建了一整套空地两栖机器人,使用Prometheus开源框架完成算法的仿真验证与…...
python小记(十二):Python 中 Lambda函数详解
Python 中 Lambda函数详解 Lambda函数详解:从入门到实战一、什么是Lambda函数?二、Lambda的核心语法与特点1. 基础语法2. 与普通函数对比 三、Lambda的六大应用场景(附代码示例)1. 基本数学运算2. 列表排序与自定义规则3. 数据映射…...
第二十一讲 XGBoost 回归建模 + SHAP 可解释性分析(利用R语言内置数据集)
下面我将使用 R 语言内置的 mtcars 数据集,模拟一个完整的 XGBoost 回归建模 SHAP 可解释性分析 实战流程。我们将以预测汽车的油耗(mpg)为目标变量,构建 XGBoost 模型,并用 SHAP 来解释模型输出。 🚗 示例…...
数据分析实战案例:使用 Pandas 和 Matplotlib 进行居民用水
原创 IT小本本 IT小本本 2025年04月15日 18:31 北京 本文将使用 Matplotlib 及 Seaborn 进行数据可视化。探索如何清理数据、计算月度用水量并生成有价值的统计图表,以便更好地理解居民的用水情况。 数据处理与清理 读取 Excel 文件 首先,我们使用 pan…...
Asp.NET Core WebApi 创建带鉴权机制的Api
构建一个包含 JWT(JSON Web Token)鉴权的 Web API 是一种常见的做法,用于保护 API 端点并验证用户身份。以下是一个基于 ASP.NET Core 的完整示例,展示如何实现 JWT 鉴权。 1. 创建 ASP.NET Core Web API 项目 使用 .NET CLI 或 …...
hash.
Redis 自身就是键值对结构 Redis 自身的键值对结构就是通过 哈希 的方式来组织的 哈希类型中的映射关系通常称为 field-value,用于区分 Redis 整体的键值对(key-value), 注意这里的 value 是指 field 对应的值,不是键…...
记录鸿蒙应用上架应用未配置图标的前景图和后景图标准要求尺寸1024px*1024px和标准要求尺寸1024px*1024px
审核报错【①应用未配置图标的前景图和后景图,标准要求尺寸1024px*1024px且需下载HUAWEI DevEco Studio 5.0.5.315或以上版本进行图标再处理、②应用在展开状态下存在页面左边距过大的问题, 应用在展开状态下存在页面右边距过大的问题, 当前页面左边距: 504 px, 当前页面右边距…...
golang-常见的语法错误
https://juejin.cn/post/6923477800041054221 看这篇文章 Golang 基础面试高频题详细解析【第一版】来啦~ 大叔说码 for-range的坑 func main() { slice : []int{0, 1, 2, 3} m : make(map[int]*int) for key, val : range slice {m[key] &val }for k, v : …...
Google最新《Prompt Engineering》白皮书全解析
近期有幸拿到了Google最新发布的《Prompt Engineering》白皮书,这是一份由Lee Boonstra主笔,Michael Sherman、Yuan Cao、Erick Armbrust、Antonio Gulli等多位专家共同贡献的权威性指南,发布于2025年2月。今天我想和大家分享这份68页的宝贵资…...
如何快速部署基于Docker 的 OBDIAG 开发环境
很多开发者对 OceanBase的 SIG社区小组很有兴趣,但如何将OceanBase的各类工具部署在开发环境,对于不少开发者而言都是比较蛮烦的事情。例如,像OBDIAG,其在WINDOWS系统上配置较繁琐,需要单独搭建C开发环境。此外&#x…...
