目录
前言:
替换所有的问号
题目解析
算法原理
算法编写
提莫攻击
题目解析
算法原理
算法编写
外观数列
题目解析
算法原理
算法编写
前言:
本文的主题是模拟,通过三道题目讲解,一道是提莫攻击,一道是替换所有的问好,一道是外观数列。
链接分别为:
1576. 替换所有的问号 - 力扣(LeetCode) 38. 外观数列 - 力扣(LeetCode)
495. 提莫攻击 - 力扣(LeetCode)
题目分为三个部分讲解,一是题目解析,二是算法原理,三是算法编写,那么,话不多说,直接进行主题咯。
替换所有的问号
题目解析
题目的要求是替换字符串里面所有的问号,而字符串里面只有小写英文和问号,我们需要将?转换为小写的字母,转换之后,前后不能有连续的相同的字符,并且我们不能够修改非?字符,也就是只能修改问号咯,这里顺带一提,为什么这种算法是模拟。
因为这种题目是比较有意思的,解法相当于已经告诉我们了,不过需要我们自己去模拟实现而已。
相对来说的话,我们在没有接触算法之前,大部分可能都是模拟的吧。
那么我们就进入到算法原理部分吧。
算法原理
算法原理……就是模拟咯,我们模拟这个过程就行。
只需要保证前后没有重复即可:
当然了,我们还有注意部分细节问题,比如问号如果在前面的话,我们就需要判断一下,如果不满足这个条件,就要判断不能和前面的相等了,问号在字符串末尾同理。
算法原理是非常简单的,遍历一次字符串就可以了。
算法编写
class Solution {
public:
string modifyString(string s)
{
for (int i = 0; i < s.size(); i++)
{
// 准备替换问号
if (s[i] == '?')
{
for (char ch = 'a'; ch < 'z'; ch++)
{
if ((i == 0 || ch != s[i - 1]) && (i == s.size() - 1 || ch != s[i + 1]))
{
s[i] = ch;
}
}
}
}
return s;
}
};
这里的判断也是比较充分的利用了||运算符的短路特点,恰好能够判断,如果i不是0或者是size -1的情况和i刚好是两种极端值的情况,只能说非常巧妙了。
提莫攻击
题目解析
各位请不要看到提莫攻击就去打lol了奥,先看题吧哈哈哈。
对于这道题,我们可以简化题目,也就是提莫的攻击有多次,每次攻击可以让敌方英雄中毒duration秒,每次攻击会冲击持续时间,要求我们返回的是总中毒秒数。
那么题目我们搞清楚了,现在进入原理部分吧!
算法原理
算法是非常简单的,就有点像高中?或者是初中的一个覆盖问题,我们只需要判断两个间隔之间的差值即可,如果两次攻击间隔之间的差值大于了持续时间,那么中毒的持续时间吃满了就,如果间隔小于持续时间,那么中毒的持续时间就相当于两次攻击间隔的时间:
不过如果走到了数组的最后,没有重置中毒的持续状态,那么直接+duration就行,这是对于边界情况的处理。
原理我们也清楚了,直接进入到算法原理编写吧!
算法编写
class Solution
{
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration)
{
int ans = 0;
for(int i = 1; i < timeSeries.size(); i++)
{
int ret = timeSeries[i] - timeSeries[i - 1];
if(ret < duration) ans += ret;
else ans += duration;
}
return ans + duration;
}
};
外观数列
题目解析
题目描述的多麻烦的,其实我们理解之后,它描述的不过是上一项的数字情况而已,默认数列第一项是1,所以第二项描述的时候,是1个1,那么第二项就是11,对于第三项描述的时候是描述第二项,第二项有两个1,所以是21。
最后求第几项的字符串组成就行。
题目要求我们懂了,现在进入算法原理部分。
算法原理
题目的要求不过就是让我们从一堆数字里面,找相同的,组成由相同数字的个数 + 数字组成的字符串而已。所以计数器是必要的,用一个指针用来指向某个特定的元素,让另一个指针一直走,直到找到不同的,然后让+=组成字符串即可。
这里穿插使用到的方法是双指针算法,让两个指针从同一个方向移动即可,并且,我们应该处理一下边界情况,最后返回结果就可以了。
对于循环部分,解释的次数相当于数组长度 - 1,因为第一次是不用解释的。
算法编写
class Solution {
public:
string countAndSay(int n) {
string ret = "1";
for(int i = 0;i < n - 1; i++)
{
string tmp;
for(int left = 0, right = 0; right < ret.size(); )
{
while(right < ret.size() && ret[left] == ret[right])
right++;
tmp += to_string(right - left) + ret[left];
left = right;
}
ret = tmp;
}
return ret;
}
};
感谢阅读!