算法篇----模拟
一、总述
模拟算法题,就是照葫芦画瓢,特点就是思路比较简单,但是比较考察代码能力,写之前一定要先在草纸上过一遍流程
二、例题
1.替换问号
1576. 替换所有的问号 - 力扣(LeetCode)
解题思路:这道题比较简单,就按照题目要求说的做就行了,没啥可讲的技巧性地方~
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.攻击问题
495. 提莫攻击 - 力扣(LeetCode)
解题思路:
这道题也是看题目所说的理解就好,简单说一下,就是比较两次攻击的差值x和duration的大小,设结果为ret,x<d,ret+=x,x>d,ret+=d;最后别忘了加上最后一次中毒的时间就好了~
比较那里可以在优化一下~,三目表达式,min函数或者if else都可以~
class Solution {
public:int findPoisonedDuration(vector<int>& timeSeries, int duration) {int n=timeSeries.size(),ret=duration;for(int i=1;i<n;i++){int x=timeSeries[i]-timeSeries[i-1];ret+=min(x,duration);}return ret;}
};
3. Z 字形变换
6. Z 字形变换 - 力扣(LeetCode)
解题思路:
这道题略微有一些复杂,又两种思路可以解决
方法一)暴力破解
利用二维数组,分析出每个“坐标”的关系,但是解起来会比较麻烦,感兴趣的可以试一下
方法二)模拟
一般这种题都可以利用找规律的方法来进行优化化简,比如,我们先举个例子,写一下下标,看看各个下标对应的关系,示例图如下:
不难发现,第一行和最后一行是一个等差数列,公差d=2n-2,之后我们在看一下中间第k行,会发现这不是严格意义上的等差数列,但是倘若我们将他们两俩个一组,发现这就是等差数列,其规律为:(k,d-k)->(k+d,d-k+d)->(k+d+d,d-k+d+d).......
再写一下第0行的规律:0->d->2d.........
再写一下第n-1行的规律:(n-1)->(n-1+d)->(n-1+2d).......
class Solution {
public:string convert(string s, int numRows) {//边界情况if(numRows==1) return s;string ret;int d=2*numRows-2,n=s.size();//处理第一行for(int i=0;i<n;i+=d)ret+=s[i];//处理中间k行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];}}//处理最后一行for(int i=numRows-1;i<n;i+=d)ret+=s[i];return ret;}
};
4.数青蛙
1419. 数青蛙 - 力扣(LeetCode)
解题思路:
这道题比较复杂了,首先要我们理解好题目,理解之后我们讨论一下如何解决~
这道题我们可以利用哈希表,先将croak映射在哈希表中,之后遍历字符串 croakOfFrogs,如果遍历到字符c,为了满足题目要求中的最少青蛙数目,我们就要看看哈希表中我们的字符k是否存在,如果存在的话,说明至少有一只青蛙叫了一遍了,那我就再抓一只青蛙回到c位置重新叫,转换成编程即最后一个字符--,c字符++,但要是不存在的话,就直接加一直青蛙,即c字符++
如果遍历到了r o a k,按照题意,那我们就要看前趋字符是否存在,如果存在,那么前趋字符--,本字符++,如果不存在,则直接返回-1
注意:为了使得解法更具有广泛性,我们可以把字符串croak也给存入哈希表,即用两个哈希表来解决本题~
class Solution {
public:int minNumberOfFrogs(string croakOfFrogs) {string t="croak";int n=t.size();vector<int> hash(n); //数组模拟哈希表,判断青蛙unordered_map<char,int> index;//存放croak,字符和下标进行映射for(int i=0;i<n;i++)index[t[i]]=i;for(auto ch:croakOfFrogs){if(ch=='c'){if(hash[n-1]) 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) //防止出现例如ccroak或者ccrroak这种例子return -1; return hash[n-1];}
};
算法篇到此结束~~