【简单】力扣算法题解析LeetCode345:反转字符串中的元音字母

关注底部名片达文汐,即可获得本题完整源码

题目来源:LeetCode345:反转字符串中的元音字母

问题抽象: 给定一个 字符数组 s(由 ASCII 字符组成),要求 原地反转数组中所有元音字母的位置(非元音字母保持原位),满足以下核心需求:

  1. 反转规则

    • 元音字母定义:小写 'a','e','i','o','u' 及大写形式(共 10 种);
    • 交换逻辑:首个元音字母与末尾元音字母交换,次个元音字母与次末元音字母交换,依此类推;
    • 非元音字母位置不变。
  2. 操作约束

    • 空间复杂度 O(1):仅允许常数级额外空间(双指针+临时变量);
    • 时间复杂度 O(n):单次遍历完成(n 为数组长度);
    • 原地修改:直接操作输入数组(无返回值或返回修改后数组)。
  3. 边界处理

    • 空数组:直接返回;
    • 无元音字母:数组保持不变;
    • 大小写敏感'A''a' 均视为元音,但交换时保留原大小写;
    • 奇偶元音数量
      • 奇数个元音时中间元音位置不变(如 "hello""holle",中间 'o' 与自身交换);
      • 偶数个元音时两两交换(如 "leetcode""leotcede")。
  4. 特殊案例

    • 输入 ["h","e","l","l","o"] → 输出 ["h","o","l","l","e"]'e''o' 交换);
    • 输入 ["l","e","e","t","c","o","d","e"] → 输出 ["l","e","o","t","c","e","d","e"]
    • 输入 ["b","c","d"] → 输出不变(无元音)。

输入:字符数组 s(长度范围 [0, 3×10^5]
输出:无返回值(s 修改为元音反转后的数组)。


解题思路

题目要求反转字符串中的元音字母(包括大小写)。采用双指针法实现高效反转:

  1. 双指针扫描:左指针 left 从头部开始,右指针 right 从尾部开始
  2. 跳过非元音:左右指针各自向中间移动,直到指向元音字母
  3. 交换元音:当左右指针都指向元音时交换它们
  4. 继续扫描:交换后左右指针同时向中间移动一位
  5. 终止条件:当 left >= right 时停止

优化点

  • 使用字符数组直接操作,避免字符串不可变性带来的开销
  • 预定义元音集合,使用 String.contains() 快速判断
  • 双指针一次遍历完成操作,时间复杂度 O(n),空间复杂度 O(n)

代码实现(Java版)🔥点击下载源码

class Solution {
    public String reverseVowels(String s) {
        if (s == null || s.isEmpty()) return s;
        char[] chars = s.toCharArray();
        int left = 0, right = chars.length - 1;
        // 元音字母集合(包含大小写)
        String vowels = "aeiouAEIOU";
        
        while (left < right) {
            // 左指针移动到元音位置
            while (left < right && vowels.indexOf(chars[left]) == -1) {
                left++;
            }
            // 右指针移动到元音位置
            while (left < right && vowels.indexOf(chars[right]) == -1) {
                right--;
            }
            // 交换两个元音字母
            if (left < right) {
                char temp = chars[left];
                chars[left] = chars[right];
                chars[right] = temp;
                left++;
                right--;
            }
        }
        return new String(chars);
    }
}

代码说明

  1. 字符数组转换s.toCharArray() 将字符串转为可修改的字符数组
  2. 双指针初始化
    • left=0 从头部开始
    • right=chars.length-1 从尾部开始
  3. 元音判断:通过 vowels.indexOf(ch) == -1 判断非元音字符
  4. 指针移动
    • 左指针遇到非元音时 left++
    • 右指针遇到非元音时 right--
  5. 交换操作:当两指针都指向元音时执行交换,并同步移动指针
  6. 结果构建:最后通过 new String(chars) 将字符数组转为字符串

复杂度分析:时间复杂度:O(n),双指针完整扫描字符串一次。空间复杂度:O(n),存储字符数组(返回结果必须的空间)


提交详情(执行用时、内存消耗)

在这里插入图片描述

我的名片👇👇👇👇👇👇👇👇👇👇👇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值