
本文详解 leetcode「反转元音字母」题目的常见错误与优化解法,重点修复索引错位、大小写遗漏及返回值类型问题,并提供简洁高效的双指针实现方案。
你的原始代码思路清晰——标记元音位置、提取元音字符、倒序填充——但存在三个关键缺陷:
- count 变量在循环中无条件递增:导致 markedItemsIndex[count] 很快越界或匹配失败(如 i=0 时 count=1,跳过首个元音);
- 未处理大写元音(如 'A', 'E'),使 'Hello' → 'Holle' 失败;
- 返回值为数组而非字符串,缺少 .join(''),不符合题目输出要求。
✅ 正确修复方式如下(修正版单次遍历逻辑):
var reverseVowels = function(s) {
const vowels = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']);
const chars = s.split('');
let left = 0, right = chars.length - 1;
while (left < right) {
// 从左找元音
while (left < right && !vowels.has(chars[left])) left++;
// 从右找元音
while (left < right && !vowels.has(chars[right])) right--;
// 交换
if (left < right) {
[chars[left], chars[right]] = [chars[right], chars[left]];
left++;
right--;
}
}
return chars.join(''); // ✅ 必须转回字符串
};? 为什么双指针更优?
- 时间复杂度 O(n),仅需一次遍历;
- 空间复杂度 O(n)(字符数组),避免额外存储索引与元音数组;
- 逻辑直观:两端向中间收缩,直接交换,无需标记/重排/计数等易错步骤。
⚠️ 注意事项:
- 使用 Set 判断元音比链式 || 或正则 /[aeiou]/i.test() 更高效(尤其在长字符串中);
- vowels.has() 区分大小写,因此显式加入大写字母(比正则更语义明确且性能略优);
- 交换后必须同时移动 left 和 right,否则陷入死循环。
运行示例:
reverseVowels("hello") → ['h','e','l','l','o'] → ['h','o','l','l','e'] → "holle" ✅
reverseVowels("Hello World!") → "Holle Werld!" ✅('e'↔'o', 'o'↔'e', '!' 非元音不参与)
总结:避免用“标记-收集-倒序填充”这类多阶段模拟逻辑,优先采用原地双指针交换——结构简洁、边界清晰、容错性强,是处理此类对称替换问题的标准范式。










