Easy
题目描述
给定一个字符串 s,其中仅包含小写英文字母和 ‘?’ 字符,将所有的 ‘?’ 字符替换为小写字母,使得最终的字符串不包含任何连续重复字符。你不能修改非 ‘?’ 字符。
保证给定字符串中除了 ‘?’ 外没有连续重复字符。
在完成所有转换(可能为零次)后,返回最终字符串。如果有多个解决方案,返回其中任何一个即可。可以证明在给定约束下总是存在答案。
示例 1:
输入:s = "?zs"
输出:"azs"
解释:这个问题有 25 种解决方案。从 "azs" 到 "yzs",都是有效的。只有 "z" 是无效的修改,因为字符串会变成 "zzs",包含连续重复字符。
示例 2:
输入:s = "ubv?w"
输出:"ubvaw"
解释:这个问题有 24 种解决方案。只有 "v" 和 "w" 是无效的修改,因为字符串会变成 "ubvvw" 和 "ubvww",包含连续重复字符。
约束:
- 1 <= s.length <= 100
- s 由小写英文字母和 ‘?’ 组成
解题思路
这是一个贪心算法问题。核心思路是从左到右遍历字符串,遇到 ‘?’ 时,找到一个字符使其与左右相邻的字符都不相同。
解题思路:
- 线性扫描:从左到右遍历字符串
- 贪心选择:对于每个 ‘?’,我们需要选择一个字符,使其与左右相邻字符都不同
- 字符选择策略:由于只需要避开最多2个字符(左边和右边),而我们有26个小写字母可选,所以总能找到合适的字符
- 实现细节:
- 检查左边字符(如果存在且已处理过)
- 检查右边字符(如果存在)
- 选择第一个不等于这两个字符的字母(通常是 ‘a’, ‘b’, ‘c’ 中的一个)
时间复杂度分析: 每个位置最多检查3个字符(‘a’, ‘b’, ‘c’),由于字符集有限,可以认为是常数时间,总体时间复杂度为 O(n)。
空间复杂度分析: 如果允许原地修改,空间复杂度为 O(1);否则需要 O(n) 空间存储结果。
代码实现
class Solution {
public:
string modifyString(string s) {
int n = s.length();
for (int i = 0; i < n; i++) {
if (s[i] == '?') {
for (char c = 'a'; c <= 'z'; c++) {
bool valid = true;
// 检查左边字符
if (i > 0 && s[i-1] == c) {
valid = false;
}
// 检查右边字符
if (i < n-1 && s[i+1] == c) {
valid = false;
}
if (valid) {
s[i] = c;
break;
}
}
}
}
return s;
}
};
class Solution:
def modifyString(self, s: str) -> str:
s = list(s) # 转换为可修改的列表
n = len(s)
for i in range(n):
if s[i] == '?':
for c in 'abc': # 通常前三个字母就够了
valid = True
# 检查左边字符
if i > 0 and s[i-1] == c:
valid = False
# 检查右边字符
if i < n-1 and s[i+1] == c:
valid = False
if valid:
s[i] = c
break
return ''.join(s)
public class Solution {
public string ModifyString(string s) {
char[] chars = s.ToCharArray();
int n = chars.Length;
for (int i = 0; i < n; i++) {
if (chars[i] == '?') {
for (char c = 'a'; c <= 'z'; c++) {
bool valid = true;
// 检查左边字符
if (i > 0 && chars[i-1] == c) {
valid = false;
}
// 检查右边字符
if (i < n-1 && chars[i+1] == c) {
valid = false;
}
if (valid) {
chars[i] = c;
break;
}
}
}
}
return new string(chars);
}
}
/**
* @param {string} s
* @return {string}
*/
var modifyString = function(s) {
let chars = s.split('');
let n = chars.length;
for (let i = 0; i < n; i++) {
if (chars[i]
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n) | 遍历字符串一次,每个位置最多检查3个字符 |
| 空间复杂度 | O(1) 或 O(n) | 原地修改为O(1),创建新字符串为O(n) |