
本文详解 leetcode「反转元音字母」题目的常见错误与高效解法,重点修复索引错位、大小写遗漏及字符串拼接问题,并提供优化后的双指针实现方案。
你的原始代码逻辑方向基本正确——识别元音、记录位置与字符、再反向填充——但存在三个关键缺陷,导致 'hello' 无法输出 'holle':
count 变量误用:在第二轮遍历中,count++ 被放在 for 循环体顶层,导致它每轮都自增,而非仅在匹配到目标索引时才推进。结果是 markedItemsIndex[count] 很快越界或错位,if (i === markedItemsIndex[count]) 几乎永不成立(因此 'here' 不打印)。
元音判定不完整:只检查了小写 a, i, u, e, o,而题目要求区分大小写无关(如 'Hello' 应输出 'Holle')。硬编码多个 === 条件既冗长又易漏,应使用正则 /[aeiou]/i(i 标志启用忽略大小写匹配)。
返回值类型错误:return newString 返回的是字符数组,而题目要求返回字符串。必须调用 .join('')。
✅ 修正后的简洁实现(推荐双指针法,更优时间/空间复杂度):
var reverseVowels = function(s) {
const vowels = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']);
let arr = s.split('');
let left = 0, right = arr.length - 1;
while (left < right) {
// 从左找元音
while (left < right && !vowels.has(arr[left])) left++;
// 从右找元音
while (left < right && !vowels.has(arr[right])) right--;
// 交换
if (left < right) {
[arr[left], arr[right]] = [arr[right], arr[left]];
left++;
right--;
}
}
return arr.join(''); // ✅ 关键:转回字符串
};? 为什么双指针更优?
- 时间复杂度:O(n),仅一次遍历;原方法需两次遍历 + 数组操作,实际也是 O(n),但常数更大。
- 空间复杂度:O(n)(字符数组),与原方法一致,但无需额外存储索引与元音列表,逻辑更清晰、不易出错。
- 可读性与健壮性:避免手动维护 count 和索引映射,天然支持大小写,无越界风险。
⚠️ 注意事项总结:
- 元音集合务必包含大写('A', 'E', ...)或使用 /[aeiou]/i.test(char);
- 字符串不可变,必须转为数组操作后 join('');
- 双指针中 while 内需重复检查 left
- 交换使用解构赋值 [a, b] = [b, a] 简洁安全。
运行 reverseVowels("hello") → "holle",reverseVowels("Hello World!") → "Holle Werld!",完全符合预期。










