题目描述
给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。元音字母包括’a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现不止一次。
解析
这题主要是需要知道怎么去反转元素,一般想法可能是先找元音,然后再反着放回去,实际上逆序可以是头尾往里依次交换,有点像快排操作方式。然后就是怎么去判断元音字母,最简单的就是写10个if判断,简化一下都转化为小写也需要写5个if,实际上可以用String的indexOf方法,这个函数返回字符串中字符的位置,如果不存在则返回-1,因此可以通过判断字符串aeiouAEIOU中是否含有字符来判断该字符是否为元音字符。
class Solution {
public static String reverseVowels(String s) {
StringBuilder res = new StringBuilder(s);
int left = 0;
int right = s.length() - 1;
String vowels = "aeiouAEIOU";
while (left < right) {
while (left < right && vowels.indexOf(res.charAt(left)) == -1) {
left++;
}
while (left < right && vowels.indexOf(res.charAt(right)) == -1) {
right--;
}
if (left < right) {
char tmp = res.charAt(left);
res.setCharAt(left, res.charAt(right));
res.setCharAt(right, tmp);
left++;
right--;
}
}
return res.toString();
}
}
字符数组
StringBuilder虽然是为了减少字符串操作的开销而设计的,但它的内部实现仍然涉及到对字符数组的封装和可能的内存重新分配,而字符数组提供了直接的、随机的内存访问。
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;
}
}
其他
然后是官方解答下面有人提到写了多少年C++代码下面的代码看不懂。
auto isVowel = [vowels = "aeiouAEIOU"s](char ch) {
return vowels.find(ch) != string::npos;
};
咋一看大致能看懂是什么,但是没有写过这种代码就去查了一下。
首先auto是自动推导isVowel的类型,这个是C++11的标准,当初本科学C++的时候就是学的11,所以还是了解一点,它能够使编译器能够自动确定变量的类型,这里的isVowel就是一个bool类型的函数对象。但是后面的[vowels = "aeiouAEIOU"s]
就不太了解了。不过先说说Lambda表达式,基本写法就是auto lambda = [](int x, int y) { return x + y; };
,其实有点像函数的写法,() 和{}对应了函数的传参和函数主体部分。[]用来定义捕获列表,捕获列表决定了 lambda 函数体可以访问哪些外部变量以及如何访问它们。下面是一些列子。
- [ ] - 不捕获任何外部变量。
- [=] - 以值的方式捕获外部作用域中所有变量。
- [&] - 以引用的方式捕获外部作用域中所有变量。
- [x] - 仅以值的方式捕获外部变量 x。
- [&x] - 仅以引用的方式捕获外部变量 x。
- [=, &x] - 以值的方式捕获所有外部变量,但是 x 是以引用的方式捕获。
- [&, x] - 以引用的方式捕获所有外部变量,但是 x 是以值的方式捕获。
这里实际上就是在 lambda 捕获列表中初始化 vowels变量,具体在捕获列表里面初始化是因为这种方式可以使vowels字符串只被创建和初始化一次。之后,每次调用 isVowe时,不需要重新创建和初始化vowels字符串。
回到vowels = "aeiouAEIOU"s,这个实际上是C++14引入的新特性,用来简化string创建,需要写上 using namespace std::string_literals
,下面是一些其他的列子。
#include <vector>
#include <array>
#include <map>
int main() {
// 基本数据类型
int x{5};
double y{3.14};
// STL 容器
std::vector<int> v{1, 2, 3, 4, 5};
std::array<int, 3> a{ {1, 2, 3} }; // 注意双花括号是必需的
std::map<std::string, int> m{{"one", 1}, {"two", 2}};
// 结构体
struct Point {
int x, y;
};
Point p{10, 20};
return 0;
}