描述
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
示例 1:
输入:"hello"
输出:"holle"
示例 2:
输入:"leetcode"
输出:"leotcede"
提示:
元音字母不包含字母 "y" 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-vowels-of-a-string/
求解
class Solution {
private:
std::unordered_set<char> vowelsRec{'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
public:
// 方法一,申请额外的空间存储元音字母,时间复杂度O(N), 空间复杂度O(K),其中K < N
string reverseVowels_1e(string s) {
string strVowels;
const int n = s.size();
for (int i = 0; i < n; ++i) {
char lc = tolower(s[i]); //转换为小写字母确定是否是元音字母,减少条件判断
if (lc == 'a' || lc == 'e' || lc == 'i' || lc == 'o' || lc == 'u') {
strVowels.push_back(s[i]);
}
}
std::reverse(strVowels.begin(), strVowels.end());
int k = 0;
for (int i = 0; i < n; ++i) {
char lc = tolower(s[i]);
if (lc == 'a' || lc == 'e' || lc == 'i' || lc == 'o' || lc == 'u') {
s[i] = strVowels[k++];
}
}
return s;
}
// 方法二,指针对撞,直接原地修改,时间复杂度O(N), 空间复杂度O(1)
string reverseVowels_2e(string s) {
const int n = s.size();
int low = 0;
int high = n - 1;
while (low < high) {
char llc = tolower(s[low]);
while (low < n - 1 && (llc != 'a' && llc != 'e' && llc != 'i' && llc != 'o' && llc != 'u')) {
llc = tolower(s[++low]);
}
char lhc = tolower(s[high]);
while (high > 0 && (lhc != 'a' && lhc != 'e' && lhc != 'i' && lhc != 'o' && lhc != 'u')) {
lhc = tolower(s[--high]);
}
if (low > high) {
return s;
}
std::swap(s[low], s[high]);
++low;
--high;
}
return s;
}
// 方法二优化版,将元音字母的条件修改为查询,指针对撞,直接原地修改,时间复杂度O(N), 空间复杂度O(1)
string reverseVowels(string s) {
const int n = s.size();
int low = 0;
int high = n - 1;
while (low < high) {
while (low < n - 1 && (vowelsRec.count(s[low]) == 0)) {
++low;
}
while (high > 0 && (vowelsRec.count(s[high]) == 0)) {
--high;
}
if (low > high) {
return s;
}
std::swap(s[low], s[high]);
++low;
--high;
}
return s;
}
};