反转字符串中的元音字母
难度:
标签:
题目描述
给你一个字符串 s
,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 'a'
、'e'
、'i'
、'o'
、'u'
,且可能以大小写两种形式出现不止一次。
示例 1:
输入:s = "hello" 输出:"holle"
示例 2:
输入:s = "leetcode" 输出:"leotcede"
提示:
1 <= s.length <= 3 * 105
s
由 可打印的 ASCII 字符组成
代码结果
运行时间: 30 ms, 内存: 16.9 MB
/*
* 思路:
* 1. 使用双指针法,一个指针从字符串的开头开始,另一个指针从字符串的结尾开始。
* 2. 当两个指针都指向元音字母时,交换这两个元音字母。
* 3. 移动指针继续检查,直到两个指针相遇。
* 4. 使用Java Stream来处理字符数组。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public String reverseVowels(String s) {
if (s == null || s.length() == 0) return s;
List<Character> vowels = Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U');
List<Character> vowelsInS = s.chars()
.mapToObj(c -> (char) c)
.filter(vowels::contains)
.collect(Collectors.toList());
Collections.reverse(vowelsInS);
Iterator<Character> iterator = vowelsInS.iterator();
return s.chars()
.mapToObj(c -> vowels.contains((char) c) ? iterator.next() : (char) c)
.map(String::valueOf)
.collect(Collectors.joining());
}
}
解释
方法:
本题解使用双指针的方法来解决反转字符串中元音字母的问题。具体思路如下:
1. 定义一个哈希表 table 存储所有元音字母,方便后续判断字符是否为元音字母。
2. 定义双指针 left 和 right,分别指向字符串的开头和结尾。
3. 将字符串转换为列表 ss,方便修改字符。
4. 当 left 小于 right 时,进入循环:
- 如果 ss[left] 和 ss[right] 都是元音字母,则交换两个字符,并将 left 右移、right 左移。
- 如果 ss[left] 是元音字母而 ss[right] 不是,则 right 左移。
- 如果 ss[left] 不是元音字母而 ss[right] 是,则 left 右移。
- 如果 ss[left] 和 ss[right] 都不是元音字母,则 left 右移、right 左移。
5. 循环结束后,将列表 ss 重新拼接为字符串并返回结果。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么选择将字符串转换为列表来进行字符交换,直接修改字符串不可以吗?
▷🦆
在判断字符是否为元音时,使用哈希表与直接使用字符串比较有什么优势?
▷🦆
哈希表中包含元音字母的大写和小写形式,这是否意味着算法对大小写敏感?
▷🦆
在结束循环的条件是`left < right`,这样的条件是否能确保所有元音字母都被考虑到了?还是可能有遗漏?
▷