模拟算法实战:字符串处理专题
本专题聚焦于模拟类算法,通过遍历、状态机及周期规律分析,解决五个经典的字符串与序列问题。重点在于边界条件的判断与时间复杂度的优化。
1. 替换所有的问号 (LeetCode 1576)
题目描述:
给定一个只包含小写英文字母和问号 ? 的字符串 s。你需要将所有的 ? 替换为小写字母,使得最终结果中不包含连续重复的字符。
思路
纯模拟即可。从前往后遍历整个字符串,找到问号之后,就用 a~z 的每一个字符去尝试替换。关键在于检查替换后的字符是否与左右邻居相同。
代码实现
class Solution {
public:
string modifyString(string s) {
for (int i = 0; i < s.size(); i++) {
if (s[i] == '?') {
// 尝试 a-z 替换
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;
break;
}
}
}
}
return s;
}
};
2. 提莫攻击 (LeetCode 495)
题目描述:
在《英雄联盟》的世界中,提莫的攻击可以让目标中毒。给定一个非递减的整数数组 timeSeries 表示攻击时间点,以及 duration 表示中毒持续时间。计算总中毒时间。
思路
核心是计算相邻两个时间点的差值。如果差值大于等于中毒时间,说明上次中毒可以持续完整时长;如果差值小于中毒时间,则上次的中毒只能持续两者的差值。最后别忘了加上最后一次攻击的完整中毒时间。
代码实现
class {
:
{
ret = ;
n = timeSeries.();
( i = ; i < n; i++) {
x = timeSeries[i] - timeSeries[i - ];
(x >= duration) {
ret += duration;
} {
ret += x;
}
}
ret + duration;
}
};


