6.1 模拟专题:LeetCode 1576. 替换所有的问号

发布于:2025-03-26 ⋅ 阅读:(31) ⋅ 点赞:(0)
1. 题目链接

LeetCode 1576. 替换所有的问号


2. 题目描述

给定一个仅包含小写字母和问号 '?' 的字符串 s,要求将所有 '?' 替换为任意小写字母,使得替换后的字符串中 没有相邻的两个字符相同
示例

  • 输入:s = "?zs" → 输出:"azs"(第一个 '?' 替换为 'a')。
  • 输入:s = "ubv?w" → 输出:"ubvaw"'?' 替换为 'a')。

3. 示例分析
  1. 简单替换
    • 输入:"a?b" → 输出:"acb"'?' 替换为 'c')。
  2. 边界处理
    • 输入:"??" → 输出:"ab"(两个 '?' 分别替换为 'a''b')。
  3. 复杂替换
    • 输入:"a?a" → 输出:"aba"(中间的 '?' 替换为 'b')。

4. 算法思路

核心思想

  1. 遍历字符串
    • 从左到右逐个字符处理,遇到 '?' 时进行替换。
  2. 字符选择策略
    • 'a''z' 依次尝试,选择第一个满足以下条件的字符:
      • 与左侧字符不同(若存在)。
      • 与右侧字符不同(若存在)。
  3. 左右判断
    • 每次替换只关注当前字符的左右邻居,确保局部最优,从而保证全局最优。

时间复杂度:O(n * 26) → O(n),其中 n 为字符串长度。
空间复杂度:O(1),无需额外空间。


5. 边界条件与注意事项
  1. 边界处理
    • '?' 位于字符串开头时,只需保证与右侧字符不同。
    • '?' 位于字符串末尾时,只需保证与左侧字符不同。
  2. 字符范围
    • 仅需替换为小写字母 'a'-'z',无需处理其他字符。
  3. 相邻字符冲突
    • 若左右字符相同(如 "a?a"),中间的 '?' 必须选择一个与两者不同的字符。

6. 代码实现
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++) {
                    bool leftOk = (i == 0) || (s[i-1] != ch);   // 左侧无冲突
                    bool rightOk = (i == s.size()-1) || (s[i+1] != ch); // 右侧无冲突
                    if (leftOk && rightOk) {
                        s[i] = ch;
                        break; // 找到第一个可行字符后立即终止
                    }
                }
            }
        }
        return s;
    }
};

在这里插入图片描述


关键代码解析

  1. 遍历字符串

    for (int i = 0; i < s.size(); i++)
    
    • 逐个字符检查是否为 '?'
  2. 字符替换逻辑

    for (char ch = 'a'; ch <= 'z'; ch++)
    
    • 'a''z' 依次尝试,找到第一个满足条件的字符。
  3. 条件检查

    bool leftOk = (i == 0) || (s[i-1] != ch);
    bool rightOk = (i == s.size()-1) || (s[i+1] != ch);
    
    • leftOk:若 '?' 在开头,无需检查左侧;否则检查左侧字符是否不同。
    • rightOk:若 '?' 在末尾,无需检查右侧;否则检查右侧字符是否不同。
  4. 替换并终止

    if (leftOk && rightOk) {
        s[i] = ch;
        break;
    }
    
    • 找到第一个可行字符后立即替换并跳出循环,保证时间复杂度最优。

与其他解法的对比

方法 时间复杂度 空间复杂度 核心思想
模拟算法 O(n) O(1) 逐个替换,选择第一个可行字符
预填充法 O(n) O(1) 预先处理所有 '?' 的位置
随机替换法 O(n) O(1) 随机选择字符,可能需重试