leetcode刷题(模拟问题)

题一:替换所有的问号

 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;
            else
                sum += 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;
    }
};


 

  • 20
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值