目录
[1. 替换所有的问号](#1. 替换所有的问号)
[3. Z 字形变换](#3. Z 字形变换)
前言
本篇博客是对模拟算法一部分经典题目的整理与每道题很详细的思考与题解过程,相信大家看完能对模拟类型的相关问题有一定的理解和掌握
算法概述

模拟这一块的话就没啥固定的套路了,就是一定要读好题目,根据题目的思路进行模拟,完全按照题目描述的规则、步骤去一步步执行,不需要复杂的算法设计,重点在于精准还原过程,然后转换为代码
1. 替换所有的问号

算法原理
其实模拟类型题目的算法原理就是根据题意依葫芦画瓢,不会特别复杂

解题代码:c++
cpp
class Solution {
public:
string modifyString(string s)
{
//模拟
int n=s.size();
//从前往后进行扫描
for(int i=0;i<n;i++)
{
if(s[i]=='?') //替换
{
for(char ch='a';ch<='z';ch++)
{
//判断该字符和前面相等不相等
//同时判断该字符和后面的字符相等不相等
if((i==0||ch!=s[i-1])&&(i==n-1||ch!=s[i+1]))
{
s[i]=ch; //此时才替换
break;
}
}
}
}
return s;
}
};
2.提莫攻击

题目解析:

算法原理

- 其实就是根据题意,如果这个数组中两个数的范围小于d,说明中毒时间未耗尽时又重置的中毒时间,那么此时加上的就是两数之差,如果两数之差大于等于d,说明这个范围内中毒时间耗尽了才重置,那么就加上d,而数组中最后一个元素表示最后一次重置,由于后面就没有进行重置了,为最后一次中毒,此时也应该再加个d,最终累加出来的就是答案
解题代码:c++
模拟类型题目的代码基本就是将上面的模拟过程用代码的方式写一遍
cpp
class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration)
{
//根据题目进行模拟
int ret=0;
for(int i=1;i<timeSeries.size();i++)
{
if(timeSeries[i]-timeSeries[i-1]>=duration)
ret+=duration;
else ret+=(timeSeries[i]-timeSeries[i-1]);
}
//再把最后一次累加上再返回
return ret+duration;
}
};
3. Z 字形变换

Z字形变换就是原来的N字形变换
题目解析:

算法原理

解题代码:c++
cpp
class Solution {
public:
string convert(string s, int numRows)
{
//模拟+找规律优化
//先处理一下边界情况
if(numRows==1) return s;
string ret;
int d=2*numRows-2,n=s.size();
//1.先处理第一行
for(int i=0;i<n;i+=d)
ret+=s[i];
//2.处理中间行
for(int k=1;k<numRows-1;k++) //枚举每一行
{
for(int i=k,j=d-k;i<n||j<n;i+=d,j+=d)
{
//i和j都不能越界
if(i<n) ret+=s[i];
if(j<n) ret+=s[j];
}
}
//3.处理最后一行
for(int i=numRows-1;i<n;i+=d)
ret+=s[i];
return ret;
}
};
4.外观数列

算法原理

解题代码:c++
cpp
class Solution {
public:
string countAndSay(int n)
{
//模拟+双指针
string s="1";
for(int i=1;i<n;i++)
{
int left=0,right=0,count=0;
string tmp;
while(right<s.size())
{
while(s[right]==s[left]) right++;
count=right-left;
tmp+=to_string(count)+s[left];
left=right;
}
s=tmp;
}
return s;
}
};
5.数青蛙

算法原理

解题代码:c++
cpp
class Solution {
public:
int minNumberOfFrogs(string croakOfFrogs)
{
//模拟+哈希表
string t="croak";
int n=t.size();
vector<int> hash(n); //用数组模拟哈希表
unordered_map<char,int> index; //[x,x这个字符对应的下标]
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]++;
}
}
//判断hash中最后位置前面是否有不为0的情况
//此时表示有一种叫声没有叫到最后,不会发出声音,返回-1
for(int i=0;i<n-1;i++)
{
if(hash[i]!=0) return -1;
}
return hash[n-1];
}
};