LeetCode-05-元音字符翻转

LeetCode算法题:字符串中元音字符翻转。

题目

LeetCode:LeetCode 75 - 学习计划-05-反转字符串中的元音字母

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。

元音字母包括 'a''e''i''o''u',且可能以大小写两种形式出现不止一次。

思路

待查找字符已知,从左右两端搜索对应值即可。

代码

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
30
31
32
33
34
35
36
37
38
39
40
41
42
int isVowels(char ch);

char* reverseVowels(char* s) {
assert(s);

char* left = s;
char* right = s + strlen(s) - 1;

while(right - left > 0)
{
if(isVowels(*left))
{
left++;
}
else if(isVowels(*right))
{
right--;
}
else
{
int tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
return s;
}

const char arrVowels[10] = {'a','A','o','O','e','E','i','I','u','U'};
int isVowels(char ch)
{
for(int i=0;i<sizeof(arrVowels)/sizeof(char);i++)
{
if(arrVowels[i] == ch)
{
return 0;
}
}
return 1;
}

该方案使用const数组对字符进行封装,适合多次调用时功能的扩展移植。功能采用单个while循环完成,但内部if-else会影响流水线,因此进行优化为双重循环。

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
char* reverseVowels(char* s) {
assert(s);

char* left = s;
char* right = s + strlen(s) - 1;

while(right - left > 0)
{
while(isVowels(*left))
{
left++;
}
while(isVowels(*right))
{
right--;
}
else
{
int tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
return s;
}

如果向修改isVowels函数,可以调整为如下:

1
2
3
4
5
6
7
8
9
10
11
12
const char arrVowels[10] = {'a','A','o','O','e','E','i','I','u','U'};
bool isVowels(char ch)
{
for(int i=0;i<sizeof(arrVowels)/sizeof(char);i++)
{
if(arrVowels[i] == ch)
{
return false;
}
}
return true;
}

而若调用次数不多,可使用以下代码,逻辑或||相对于逻辑与&&减少判断次数,加快运行时间:

1
2
3
4
5
6
7
8
9
10
bool isVowels(char ch)
{
/*
if(ch!='a'&& ch!='A'&& ch!='o'&& ch!='O'&& ch!='e'&& ch!='E'&& ch!='i'&& ch!='I'&&ch!='u'&& ch!='U')
return 1;
else
return 0;
*/
return (ch=='a'|| ch=='A'|| ch=='o'|| ch=='O'|| ch=='e'|| ch=='E'|| ch=='i'|| ch=='I'||ch=='u'|| ch=='U');
}

————————— End —————————

缺月挂疏桐,漏断人初静。–《卜算子·黄州定慧院寓居作》