目录
- 基础
- 经典例题
- 1576. [替换所有的问号](https://leetcode.cn/problems/replace-all-s-to-avoid-consecutive-repeating-characters/description/)
- 495.[ 提莫攻击](https://leetcode.cn/problems/teemo-attacking/submissions/460223504/)
- [6. Z 字形变换](https://leetcode.cn/problems/zigzag-conversion/)
- [38. 外观数列](https://leetcode.cn/problems/count-and-say/description/)
- [1419. 数青蛙](https://leetcode.cn/problems/minimum-number-of-frogs-croaking/description/)
基础
模拟类型的算法题就是根据题目的要求,使用代码模拟实现某个过程,有时可能会需要找规律来对代码进行一定的优化。
经典例题
1576. 替换所有的问号
给你一个仅包含小写英文字母和 ‘?’ 字符的字符串 s,请你将所有的 ‘?’ 转换为若干小写字母,使最终的字符串不包含任何 连续重复 的字符。
注意:你 不能 修改非 ‘?’ 字符。
题目测试用例保证 除 ‘?’ 字符 之外,不存在连续重复的字符。
在完成所有转换(可能无需转换)后返回最终的字符串。如果有多个解决方案,请返回其中任何一个。可以证明,在给定的约束条件下,答案总是存在的。
class Solution {
public:string modifyString(string s) {int i=0;for(;i<s.size();++i){if('?'!=s[i]){continue;}char c='a';if(i>0){c=s[i-1]+1;c='a'+(c-'a')%26;}while(i+1<s.size()&&c==s[i+1]){c++;c='a'+(c-'a')%26;}s[i]=c;}return s;}
};
495. 提莫攻击
在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。
当提莫攻击艾希,艾希的中毒状态正好持续 duration 秒。
正式地讲,提莫在 t 发起攻击意味着艾希在时间区间 [t, t + duration - 1](含 t 和 t + duration - 1)处于中毒状态。如果提莫在中毒影响结束 前 再次攻击,中毒状态计时器将会 重置 ,在新的攻击之后,中毒影响将会在 duration 秒后结束。
给你一个 非递减 的整数数组 timeSeries ,其中 timeSeries[i] 表示提莫在 timeSeries[i] 秒时对艾希发起攻击,以及一个表示中毒持续时间的整数 duration 。
返回艾希处于中毒状态的 总 秒数。
int findPoisonedDuration(int* timeSeries, int timeSeriesSize, int duration)
{int wholetime=0;int i=0;for(i=0;i+1<timeSeriesSize;++i){if(timeSeries[i]+duration<=timeSeries[i+1]){wholetime+=duration;}else{wholetime+=timeSeries[i+1]-timeSeries[i];}}wholetime+=duration;return wholetime;
}
6. Z 字形变换
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:
P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。
请你实现这个将字符串进行指定行数变换的函数
找规律这道题就可以很好地解决
class Solution {
public:string convert(string s, int numRows) {if(1==numRows){return s;}int i=0;string ans;for(i=0;i<numRows;++i){int j=i;int k=1;int span1=2*(numRows-i-1);int span2=2*i;span1=(0==span1?span2:span1);span2=(0==span2?span1:span2);while(j<s.size()){ans+=s[j];1==k%2?j+=span1:j+=span2;k++;}}return ans;}
};
38. 外观数列
「外观数列」是一个数位字符串序列,由递归公式定义:
countAndSay(1) = “1”
countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。
行程长度编码(RLE)是一种字符串压缩方法,其工作原理是通过将连续相同字符(重复两次或更多次)替换为字符重复次数(运行长度)和字符的串联。例如,要压缩字符串 “3322251” ,我们将 “33” 用 “23” 替换,将 “222” 用 “32” 替换,将 “5” 用 “15” 替换并将 “1” 用 “11” 替换。因此压缩后字符串变为 “23321511”。
给定一个整数 n ,返回 外观数列 的第 n 个元素。
class Solution {
public:string countAndSay(int n) {if(1==n){return "1";}string ret=countAndSay(n-1);string ans;int i=1;int count=1;for(;i<=ret.size();++i){if(i==ret.size()||ret[i-1]!=ret[i]){ans+=to_string(count);ans.push_back(ret[i-1]);count=1;continue;}++count;}return ans;}
};
1419. 数青蛙
给你一个字符串 croakOfFrogs,它表示不同青蛙发出的蛙鸣声(字符串 “croak” )的组合。由于同一时间可以有多只青蛙呱呱作响,所以 croakOfFrogs 中会混合多个 “croak” 。
请你返回模拟字符串中所有蛙鸣所需不同青蛙的最少数目。
要想发出蛙鸣 “croak”,青蛙必须 依序 输出 ‘c’, ’r’, ’o’, ’a’, ’k’ 这 5 个字母。如果没有输出全部五个字母,那么它就不会发出声音。如果字符串 croakOfFrogs 不是由若干有效的 “croak” 字符混合而成,请返回 -1 。
使用一个哈希表分别记录正在发出声音c、r、o、a、k的青蛙的个数,遍历字符串 croakOfFrogs,如果是字符r、o、a、k之一,如果它的前一个字符的数量为0,说明该字符串不是有效字符,直接返回-1即可,否则前一个字符的数量减1,当前字符的数量加1;如果当前当前字符是c,先对当前字符的数量加1,接着检查字符k的数量是否为0,非0就减1,否则什么也不做。遍历结束后,如果c、r、o、a对应的数量为0,说明字符串是有效字符,k对应的数量就是模拟字符串中所有蛙鸣所需不同青蛙的最少数目,否则说明字符串无效返回-1。
class Solution {
public:int minNumberOfFrogs(string croakOfFrogs) {map<char,int> mp;mp['c']=0;mp['r']=1;mp['o']=2;mp['a']=3;mp['k']=4;vector<int> count(5,0);int i=0;for(i=0;i<croakOfFrogs.size();++i){if('c'==croakOfFrogs[i]){count[0]+=1;if(count[4]){count[4]--;}}else {if(!count[mp[croakOfFrogs[i]]-1]){return -1;}count[mp[croakOfFrogs[i]]-1]--;count[mp[croakOfFrogs[i]]]++;}}for(i=0;i<4;++i){if(count[i]){return -1;}}return count[4];}
};