description
Write a function that takes a string as input and reverses the vowels in the string.
Example 1:
Input: "hello"
Output: "holle"
Example 2:
Input: "leetcode"
Output: "leotcede"
prompt:
Vowels do not contain the letter "y".
Source: LeetCode
Link: https://leetcode-cn.com/problems/reverse-vowels-of-a-string/
Solve
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;
}
};