算法40,模拟运算,替换所有的问号

题目大意

给定只包含小写字母和 ? 的字符串 s,把所有 ? 替换成小写字母,使得最终字符串中不存在两个相邻且相同的字符。

解题思路

核心结论:每个位置最多只需要考虑左右两个邻居。

  • 从左到右扫描,遇到 ? 就处理;
  • 对 a ~ z 依次尝试,只要和左边已确定的字符、右边的字符都不同,就选它;
  • 因为左右各最多占用 1 个字母,26 个字母里最多排除 2 个,必然存在可行解,且最多试 3 次就能找到,所以不需要回溯。

两个容易踩的坑:

  1. 边界越界 :i == 0 时没有左邻居,i == n - 1 时没有右邻居,需要用短路 || 保护;
  2. 右侧还是 ? :由于是从左往右处理,右边可能尚未处理。但 ? 不等于任何小写字母,所以判断天然成立,不需要特判。

参考代码(Java)

复制代码
class Solution {
    public String modifyString(String s) {
        char[] arr = s.toCharArray();
        int n = arr.length;
        for (int i = 0; i < n; i++) {
            if (arr[i] == '?') {
                for (char c = 'a'; c <= 'z'; c++) {
                    // 与左邻居不同(若存在),且与右邻居不同(若存在)
                    if ((i == 0 || arr[i - 1] != c) && (i == n - 1 || arr[i + 1] != c)) {
                        arr[i] = c;
                        break;
                    }
                }
            }
        }
        return new String(arr);
    }
}

复杂度

  • 时间复杂度:O(n) 。每个 ? 最多枚举 3 次,视为常数,整体线性。
  • 空间复杂度:O(n) (Java 字符串不可变,需转成 char[];若语言字符串可变则为 O(1))。

举例验证

以 s = "?zs" 为例:i = 0 时左无邻居,右侧是 z,枚举到 a 即满足,结果为 "azs"。

再如 s = "ubv?w":? 左为 v、右为 w,a 可用,结果为 "ubvaw"。

相关推荐
Rain的Java大神之路27 分钟前
LeetCode 37 解数独面试攻略:回溯 + 位掩码 + MRV,从暴力到毫秒级求解
java·后端·leetcode
NEFU_Jyj33 分钟前
贝尔数(组合数学)
算法
1-1=01 小时前
C# 数据结构和特殊类型
数据结构·c#·.net·.netcore
希和20271 小时前
C语言程序设计题|有序数组插入数字冒泡排序
c语言·数据结构·算法
Pniubi1 小时前
力扣73 矩阵置零
算法·leetcode·矩阵
布莱克60512 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
D e re k ZH15 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
石小石Orz15 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
民乐团扒谱机17 小时前
【微实验】NSGA-II(非支配排序遗传算法)——解决多目标优化问题的“自然选择模拟器”
linux·人工智能·算法