LC 345. 反转字符串中的元音字母

题目描述

这是 LeetCode 上的 345. 反转字符串中的元音字母 ,难度为 简单

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

示例 1:

1
2
3
输入:"hello"

输出:"holle"

示例 2:
1
2
3
输入:"leetcode"

输出:"leotcede"

提示:

  • 元音字母不包含字母 "y"

双指针

一个朴素的做法是利用「双指针」进行前后扫描,当左右指针都是元音字母时,进行互换并移到下一位。

由于元音字母相对固定,因此我们可以使用容器将其存储,并使用 static 修饰,确保整个容器的创建和元音字母的填入在所有测试样例中只会发生一次。

我们期望该容器能在 $O(1)$ 的复杂度内判断是否为元音字母,可以使用语言自带的哈希类容器($P2$ 代码)或是使用数组模拟($P1$ 代码)。

一些细节:由于题目没有说字符串中只包含字母,因此在使用数组模拟哈希表时,我们需要用当前字符减去 ASCII 码的最小值(空字符),而不是 'A'

Java 代码:

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
27
28
class Solution {
static boolean[] hash = new boolean[128];
static char[] vowels = new char[]{'a','e','i','o','u'};
static {
for (char c : vowels) {
hash[c - ' '] = hash[Character.toUpperCase(c) - ' '] = true;
}
}
public String reverseVowels(String s) {
char[] cs = s.toCharArray();
int n = s.length();
int l = 0, r = n - 1;
while (l < r) {
if (hash[cs[l] - ' '] && hash[cs[r] - ' ']) {
swap(cs, l++, r--);
} else {
if (!hash[cs[l] - ' ']) l++;
if (!hash[cs[r] - ' ']) r--;
}
}
return String.valueOf(cs);
}
void swap(char[] cs, int l, int r) {
char c = cs[l];
cs[l] = cs[r];
cs[r] = c;
}
}

Java 代码:
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
27
28
29
class Solution {
static char[] vowels = new char[]{'a','e','i','o','u'};
static Set<Character> set = new HashSet<>();
static {
for (char c : vowels) {
set.add(c);
set.add(Character.toUpperCase(c));
}
}
public String reverseVowels(String s) {
char[] cs = s.toCharArray();
int n = s.length();
int l = 0, r = n - 1;
while (l < r) {
if (set.contains(cs[l]) && set.contains(cs[r])) {
swap(cs, l++, r--);
} else {
if (!set.contains(cs[l])) l++;
if (!set.contains(cs[r])) r--;
}
}
return String.valueOf(cs);
}
void swap(char[] cs, int l, int r) {
char c = cs[l];
cs[l] = cs[r];
cs[r] = c;
}
}

C++ 代码:
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
27
28
29
class Solution {
public:
static bool hash[128];
static void initializeHash() {
static bool initialized = false;
if (!initialized) {
char vowels[] = {'a','e','i','o','u'};
for (char c : vowels) {
hash[c - ' '] = true;
hash[toupper(c) - ' '] = true;
}
initialized = true;
}
}
string reverseVowels(string s) {
initializeHash();
int l = 0, r = s.size() - 1;
while (l < r) {
if (hash[s[l]-' '] && hash[s[r]-' ']) {
swap(s[l++], s[r--]);
} else {
if (!hash[s[l]-' ']) l++;
if (!hash[s[r]-' ']) r--;
}
}
return s;
}
};
bool Solution::hash[128] = {};

Python 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution:
_hash = [False] * 128
vowels = ['a', 'e', 'i', 'o', 'u']
for c in vowels:
_hash[ord(c) - ord(' ')] = True
_hash[ord(c.upper()) - ord(' ')] = True

def reverseVowels(self, s: str) -> str:
cs = list(s)
l, r = 0, len(cs)-1
while l < r:
if self._hash[ord(cs[l]) - ord(' ')] and self._hash[ord(cs[r]) - ord(' ')]:
cs[l], cs[r] = cs[r], cs[l]
l += 1
r -= 1
else:
if not self._hash[ord(cs[l]) - ord(' ')]:
l += 1
if not self._hash[ord(cs[r]) - ord(' ')]:
r -= 1
return ''.join(cs)

  • 时间复杂度:$O(n)$
  • 空间复杂度:由于 toCharArray 会创建新数组,复杂度为 $O(n)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.345 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!