反转字符串中的元音字母:Swift 双指针一步到位

在这里插入图片描述
在这里插入图片描述

摘要

平时写代码,大家肯定经常要跟字符串打交道,不管是做输入框校验,还是批量清洗文本数据。很多时候,我们只想动字符串里的某些特定字符,比如替换、翻转、排序,其他的都不想碰。这种需求看起来简单,但做起来如果方法不对,就会很麻烦。

今天这道题就是个很典型的例子 —— 反转字符串中的元音字母。听起来小场景,其实在很多实际开发里都能用上,比如输入法候选词处理、用户昵称美化、文本自动化脚本优化等。

我们这次用 Swift 来实现,而且会聊聊这个需求背后的“开发痛点”和“双指针”这种经典解法的妙用。

描述

题目描述其实特别简单粗暴:给你一个字符串,让你把里面所有的元音字母反过来。注意,其他的字母、符号、数字,全都不能动。

元音字母就是 a、e、i、o、u,还有它们的大写版本 A、E、I、O、U。

举个例子:

  • 输入是 IceCreAm
  • 把里面的元音挑出来:I, e, e, A
  • 反转一下:A, e, e, I
  • 最后结果就是 AceCreIm

这种需求在很多实际场景里都很有用,比如:

  • 用户在 App 输入昵称时,你只想改动其中的元音部分,但保持整体格式不变。
  • 文本美化时,根据元音音节去做特殊变换。
  • 游戏里给角色名字做动态反转效果,但又不能打乱字母顺序。

痛点分析

  1. 不能整体反转,只能动“特定字符”
    有些字符串操作(比如翻转整个字符串)一行代码搞定,但像这种只想改动一部分字符,别的还不能动,就麻烦了,简单粗暴的全局方法都不行。

  2. 需要“结构不变”的处理方式
    很多实际需求是“内容变一下,排版不能乱”,尤其是跟 UI 相关的,比如用户昵称、标签文本。这就要求代码既得精准又不能影响原始结构。

  3. 性能要求高,不能用暴力解法
    特别是做批量文本处理的时候,如果你用额外数组去拆解拼装,性能会很拉胯。所以最好的做法就是尽量“原地操作”。

题解答案

解决这类问题,双指针绝对是神器。左右两边一块动,该交换的交换,不该动的直接跳过,效率高还好写。

具体做法:

  1. 把所有元音列出来,放 Set 里查找。
  2. 两个指针 left 和 right,从头和尾一起往中间走。
  3. 左边碰到非元音就右移,右边碰到非元音就左移。
  4. 一旦两个都指向元音,就交换。
  5. 循环走完,搞定。

Swift 实现代码

import Foundation

func reverseVowels(_ s: String) -> String {
    var chars = Array(s)  // 把字符串变成数组,方便直接改字符
    let vowels: Set<Character> = ["a", "e", "i", "o", "u",
                                  "A", "E", "I", "O", "U"]
    var left = 0
    var right = chars.count - 1
    
    while left < right {
        while left < right && !vowels.contains(chars[left]) {
            left += 1
        }
        while left < right && !vowels.contains(chars[right]) {
            right -= 1
        }
        
        if left < right {
            chars.swapAt(left, right)
            left += 1
            right -= 1
        }
    }
    
    return String(chars)
}

示例测试 & 结果

试几个例子感受一下:

print(reverseVowels("IceCreAm"))   // 输出: "AceCreIm"
print(reverseVowels("leetcode"))   // 输出: "leotcede"
print(reverseVowels("aA"))         // 输出: "Aa"
print(reverseVowels("swift"))      // 输出: "swift"  // 只有一个元音,不变
print(reverseVowels("AEIOU"))      // 输出: "UOIEA"

简单总结:

  • 元音有多个才会互换,像 swift 这种只有一个的,原样不动。
  • 全是元音的场景下,就会完全翻转。
  • 保持了每个字符原来的位置,其他字母和符号不会乱。

时间复杂度

只走了一遍字符串,复杂度就是 O(n),n 是字符串长度。即使用了双指针,整体遍历次数是不会变多的。

空间复杂度

用了个字符数组复制了一份字符串,空间复杂度是 O(n)
如果在 C++ 这种能直接改原字符串的语言里,可以做到 O(1) 额外空间。

实际开发场景举例

  1. 输入框校验与美化
    比如用户在注册昵称时,App 想让名字的元音部分变得“花哨”点,但又不影响用户输入的顺序。这种只改动局部字符的需求,这个解法就非常合适。

  2. 游戏文本音节调整
    某些游戏为了让角色名字显得“魔性”,会根据元音字母去做反转、替换音节,但又要求整体字母结构不能乱。这道题的方法直接套上去就行。

  3. 批量数据清洗处理
    处理日志、用户数据、文本文件时,需要针对特定字符批量做替换/反转,保持整体格式不乱,这种双指针原地修改就特别高效。

总结

这类“只动部分字符”的字符串题目,其实是开发中很常见但又特别容易掉坑的场景。双指针技巧的妙处就在于:

  • 只关注我们想改的部分;
  • 不动其他字符,保持原样;
  • 性能也能保持在线。

掌握了这个套路,很多看似麻烦的字符串问题都会迎刃而解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

网罗开发

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

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

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

打赏作者

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

抵扣说明:

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

余额充值