题目描述
给你一个字符串 s
,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 'a'
、'e'
、'i'
、'o'
、'u'
,且可能以大小写两种形式出现不止一次。
示例 1:
输入:s = "IceCreAm"
输出:"AceCreIm"
解释:
s
中的元音是 ['I', 'e', 'e', 'A']
。反转这些元音,s
变为 "AceCreIm"
.
示例 2:
输入:s = "leetcode"
输出:"leotcede"
提示:
1 <= s.length <= 3 * 105
s
由 可打印的 ASCII 字符组成
解法
方法一:双指针
我们可以用两个指针 $i$ 和 $j$,初始时分别指向字符串的首尾。
每次循环判断 $i$ 指向的字符是否是元音字母,如果不是则向后移动 $i$;同理,判断 $j$ 指向的字符是否是元音字母,如果不是则向前移动 $j$。如果此时 $i \lt j$,那么 $i$ 和 $j$ 指向的字符都是元音字母,交换这两个字符。然后向后移动 $i$,向前移动 $j$。继续上述操作,直到 $i \ge j$。
时间复杂度 $O(n)$,其中 $n$ 是字符串的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 是字符集的大小。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | class Solution:
def reverseVowels(self, s: str) -> str:
vowels = "aeiouAEIOU"
i, j = 0, len(s) - 1
cs = list(s)
while i < j:
while i < j and cs[i] not in vowels:
i += 1
while i < j and cs[j] not in vowels:
j -= 1
if i < j:
cs[i], cs[j] = cs[j], cs[i]
i, j = i + 1, j - 1
return "".join(cs)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | class Solution {
public String reverseVowels(String s) {
boolean[] vowels = new boolean[128];
for (char c : "aeiouAEIOU".toCharArray()) {
vowels[c] = true;
}
char[] cs = s.toCharArray();
int i = 0, j = cs.length - 1;
while (i < j) {
while (i < j && !vowels[cs[i]]) {
++i;
}
while (i < j && !vowels[cs[j]]) {
--j;
}
if (i < j) {
char t = cs[i];
cs[i] = cs[j];
cs[j] = t;
++i;
--j;
}
}
return String.valueOf(cs);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | class Solution {
public:
string reverseVowels(string s) {
bool vowels[128];
memset(vowels, false, sizeof(vowels));
for (char c : "aeiouAEIOU") {
vowels[c] = true;
}
int i = 0, j = s.size() - 1;
while (i < j) {
while (i < j && !vowels[s[i]]) {
++i;
}
while (i < j && !vowels[s[j]]) {
--j;
}
if (i < j) {
swap(s[i++], s[j--]);
}
}
return s;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | func reverseVowels(s string) string {
vowels := [128]bool{}
for _, c := range "aeiouAEIOU" {
vowels[c] = true
}
cs := []byte(s)
i, j := 0, len(cs)-1
for i < j {
for i < j && !vowels[cs[i]] {
i++
}
for i < j && !vowels[cs[j]] {
j--
}
if i < j {
cs[i], cs[j] = cs[j], cs[i]
i, j = i+1, j-1
}
}
return string(cs)
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | function reverseVowels(s: string): string {
const vowels = new Set(['a', 'e', 'i', 'o', 'u']);
const cs = s.split('');
for (let i = 0, j = cs.length - 1; i < j; ++i, --j) {
while (i < j && !vowels.has(cs[i].toLowerCase())) {
++i;
}
while (i < j && !vowels.has(cs[j].toLowerCase())) {
--j;
}
[cs[i], cs[j]] = [cs[j], cs[i]];
}
return cs.join('');
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | impl Solution {
pub fn reverse_vowels(s: String) -> String {
let vowel = String::from("aeiouAEIOU");
let mut data: Vec<char> = s.chars().collect();
let (mut i, mut j) = (0, s.len() - 1);
while i < j {
while i < j && !vowel.contains(data[i]) {
i += 1;
}
while i < j && !vowel.contains(data[j]) {
j -= 1;
}
if i < j {
data.swap(i, j);
i += 1;
j -= 1;
}
}
data.iter().collect()
}
}
|