题一:替换所有的问号
1.链接
1576. 替换所有的问号 - 力扣(LeetCode)
2.思路
这道题,最重要的就是理解什么是连续重复的字符
连续重复字符是指:相同字母连在一起多次出现
- 先遍历这个数组,去找到 ?出现的位置
- 找到后,就对该位置进行替换,替换的原则是:不和左右的字母相同即可
- 当找到了一个符合原则的字母,就退出循环
- 完成这个操作后,在继续往后面去找?出现的位置,继续上面操作
边界问题
由于这里会进行对 i -1 和 i + 1 位置的访问,为了避免出现数组越界访问,就单独处理 ? 出现在第一个位置和最后一个位置的情况
3.代码
class Solution {
public:string modifyString(string s) {int n = s.size();//当?出现在第一个位置if (s[0] == '?') {for (int i = 0; i <= 26; i++) {if (s[1] != i + 'a') {s[0] = i + 'a';break;}}}//当?出现在中间位置for (int i = 1; i < n; i++) {if (s[i] == '?') {for (int j = 0; j <= 26; j++)if (s[i - 1] != j + 'a' && s[i + 1] != j + 'a') {s[i] = j + 'a';break;}}}//当?出现在最后一个位置if (s[n-1] == '?' && n >= 2) {for (int i = 0; i <= 26; i++) {if (s[n - 2] != i + 'a') {s[n - 2] = i + 'a';break;}}}return s;}
};
题二:提莫攻击
1.链接
495. 提莫攻击 - 力扣(LeetCode)
2.思路
- 我们定义一个变量 sum,用来累加每次攻击所造成的中毒的时长。
- 问题的关键就是:发动攻击后,中毒时间该如何去算。此刻我们要将相邻二次攻击的时间差 ( gap )和中毒持续时间进行比较。
- 当 gap >= 中毒持续时间,那么就可以完成本次中毒所要时间
- 当 gap < 中毒持续时间,那么就会发生,本次攻击所造成的中毒还没有结束,就又开始了一次攻击,那么此刻我们去计算本次攻击所造成的中毒时间就等于 gap
本题的关键就是如何去累积算 sum ,这里我们要正确确定好每次计算中毒时长的范围。
sum 统计的是因为本次攻击所造成的中毒时长。
3.代码
class Solution {
public:int findPoisonedDuration(vector<int>& timeSeries, int duration) {int sum = 0;for (int i = 0; i < timeSeries.size() - 1; i++) {int gap = timeSeries[i + 1] - timeSeries[i];if (gap >= duration)sum += duration;elsesum += gap;}return sum + duration;}
};
题三:Z字形变换
1. 链接
6. Z 字形变换 - 力扣(LeetCode)
2.思路
这里的 Z 字形应该说是 N 字形更好。先从上往下,然后在沿对角线方向,在不断循环这个操作,直到没有字符
我们输出时,先输出第一行的,并按照从左往右的方向去输出,然后就是下一行,并也是按照从左往右去输出,这样重复操作,直到输完最后一行。
我们可以去观察原字符串数组下标与最后输出字符串的下标 ,行数的关系。
- 第一行和最后一行下标的关系是,同一行相邻二个数据下标之差等于:2*numRows - 2
- 当为中间的行数时,以示例二为例子,其Z字形的第二行为 A L S I G
- 其中 A 与 L 之间的下标差距为2*行数 - 2 ,这里的行数是:此刻黑色方框所对应的Z字形的行数
- L与S之间的下标差为:2 * 当前所处的行数
3.代码
class Solution {
public:string convert(string s, int numRows) {if (numRows == 1)return s;string ret;int gap = 2 * numRows - 2;for (int i = 0; i < numRows; i++) {int add = 2 * i, index = i;while (index < s.size()) {ret += s[index];add = gap - add;// 第一次间距是step -2*i,第二次是2*i, index += (i == 0 || i == numRows - 1) ? gap : add;}}return ret;}
};
题四: 外观数列
1.链接
38. 外观数列 - 力扣(LeetCode)
2.思路
核心思路:模拟+双指针操作
3.代码
class Solution {
public:string countAndSay(int n) {string ret = "1";for (int i = 1; i < n; i++) //只要进行n-1次操作{int left = 0, right = 0;string tmp;while (right < ret.size()) {while (ret[right] == ret[left] && right < ret.size()) {right++;}//出这个循环时,就代表此刻right所对应的值和left所对应的值不同tmp += to_string(right - left) + ret[left];left = right;}ret = tmp;}return ret;}
};