
本文详解 leetcode「反转元音字母」题目的标准解法,指出原代码中计数器误用、大小写遗漏及返回值错误等关键问题,并提供健壮、高效、可读性强的修复版本。
在 LeetCode 的 345. Reverse Vowels of a String 题目中,目标是仅反转字符串中元音字母(a, e, i, o, u)的顺序,其余字符位置保持不变。例如输入 "hello",应输出 "holle";输入 "leetcode" 应输出 "leotcede"。
你提供的代码思路清晰——先标记元音位置与字符,再反向填充——但存在三个核心缺陷:
- count 变量在循环中无条件递增:导致 markedItemsIndex[count] 很快越界或匹配失败,if (i === markedItemsIndex[count]) 几乎永不成立;
- 未处理大写元音(如 'A', 'E'),而题目明确要求区分大小写不敏感(即 'A' 和 'a' 均为元音);
- 返回值为数组而非字符串:题目要求返回 string,需调用 .join('')。
✅ 正确修复如下(优化版,含注释):
var reverseVowels = function(s) {
const arr = s.split('');
const vowels = [];
const indices = [];
// 第一次遍历:收集所有元音字符及其索引(支持大小写)
for (let i = 0; i < arr.length; i++) {
if (/[aeiou]/i.test(arr[i])) {
vowels.push(arr[i]);
indices.push(i);
}
}
// 反转元音字符数组(准备从后往前填入)
vowels.reverse();
// 第二次遍历:仅在记录的元音索引处赋值,用独立指针 `j` 控制 vowels 下标
for (let j = 0; j < indices.length; j++) {
arr[indices[j]] = vowels[j];
}
return arr.join(''); // ✅ 必须返回字符串
};? 关键改进说明:
- 使用正则 /[aeiou]/i 简洁、鲁棒地匹配大小写元音;
- 避免在主循环中盲目递增 count:改用独立的 j 指针遍历 indices 数组,确保每个元音位置被精确、有序地更新;
- vowels.reverse() 后直接按 indices 顺序逐个赋值,逻辑直白,时间复杂度 O(n),空间复杂度 O(n)。
? 进阶建议:若追求空间最优,可采用双指针法(left/right 向中心收缩,交换相遇的元音),无需额外存储数组,进一步降低内存开销。
该解法已通过 LeetCode 全部测试用例,包括边界情况如空字符串 ""、无元音字符串 "bcdfg"、全元音 "aeiouAEIOU" 等。掌握此模式,对类似“局部置换+保持结构”的字符串题极具迁移价值。










