上篇文章:位运算实战:轻松解决五大经典算法题
目录
1.替换所有的问号
https://leetcode.cn/problems/replace-all-s-to-avoid-consecutive-repeating-characters/description/


理解题意
找到?所在位置,对其进行字母替换,要求:不能和前面或后面紧连的字母相重复。
算法原理
本题中?所在的位置有三种可能:第一个,中间,最后一个。
其中,第一个和最后一个只需要判断其后一个和前一个字符,并放入不同的字符,中间的需要判断前后两个字符。
注意&&和||,这两个符号的正确使用。
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.提莫攻击
https://leetcode.cn/problems/teemo-attacking/


理解题意
根据提莫对艾希的攻击时刻,以及持续秒数,在考虑第二次攻击会重置持续秒数的前提下,返回艾希处于中毒状态的总秒数。
算法原理
本题需要正确判断中毒状态与发起攻击的时刻,之间的时间维持关系。
从1s开始,判断后一次发起攻击时间与前一次发起攻击时间的差,并与中毒持续时间相比较,如果小于中毒持续时间,那么更新返回时间为两次攻击时间之差,如果大于持续时间,那么更新结果为中毒持续时间。
注意最后添加最后一次攻击导致的中毒持续时间。
class Solution
{
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration)
{
int ret = 0;
int n = timeSeries.size();
for(int i = 1; i < n; i++)
{
int x = timeSeries[i] - timeSeries[i - 1];
if(x >= duration)
{
ret += duration;
}
else
{
ret += x;
}
}
ret += duration;
return ret;
}
};
3.Z字形变换
https://leetcode.cn/problems/zigzag-conversion/description/


理解题意
将一个字符串按照N字形按行数和顺序排列,再将产生的新字符串按横向从左往右的顺序依次输出
算法原理
本模拟题需要进行找规律,规律如下:

按照不同行数,进行不同的遍历方式。注意对极限的判断:只有一行或字符串字符数小于行数。
class Solution
{
public:
string convert(string s, int numRows)
{
string ret;
int d = 2 * numRows - 2, n = s.size();
if(numRows == 1 || n < numRows)
{
return s;
}
vector<string> str(numRows);
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;
}
};
本章完。