LeetCode 反转字符串中的元音字母:正确实现与常见错误解析

20次阅读

LeetCode 反转字符串中的元音字母:正确实现与常见错误解析

本文详解 leetcode「反转元音字母」题目的标准解法,指出原代码中计数器误用、大小写遗漏及返回值错误等关键问题,并提供健壮、高效、可读性强的修复版本。

在 LeetCode 的 345. Reverse Vowels of a String 题目中,目标是仅反转字符串中元音字母(a, e, i, o, u)的顺序,其余字符位置保持不变。例如输入 “hello”,应输出 “holle”;输入 “leetcode” 应输出 “leotcede”。

你提供的代码思路清晰——先标记元音位置与字符,再反向填充——但存在三个核心缺陷:

  1. count 变量在循环中无条件递增:导致 markedItemsIndex[count] 很快越界或匹配失败,if (i === markedItemsIndex[count]) 几乎永不成立;
  2. 未处理大写元音(如 ‘A’, ‘E’),而题目明确要求区分大小写不敏感(即 ‘A’ 和 ‘a’ 均为元音);
  3. 返回值为数组而非字符串:题目要求返回 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" 等。掌握此模式,对类似“局部置换+保持结构”的字符串题极具迁移价值。

text=ZqhQzanResources