今天的三道都是字符串反转的题目,也相对比较简单,我们先来看第一道题目:
Write a function that takes a string as input and returns the string reversed.
Example:
Given s = "hello", return "olleh".
本题没什么好说的就是一个最简单的字符串反转问题,可以自己写程序使用两个指针也可以调用内置函数,两种方法代码如下所示:
//内置函数
public String reverseString(String s) {
StringBuilder res = new StringBuilder(s);
return res.reverse().toString();
}
//双指针法
public String reverseString1(String s) {
char[] word = s.toCharArray();
int i = 0;
int j = s.length() - 1;
while (i < j) {
char temp = word[i];
word[i] = word[j];
word[j] = temp;
i++;
j--;
}
return new String(word);
}
541、 Reverse String II题目:
Given a string and an integer k, you need to reverse the first k characters for every 2k characters counting from the start of the string. If there are less than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original.
Example:
Input: s = "abcdefg", k = 2
Output: "bacdfeg"
Restrictions:
The string consists of lower English letters only.
Length of the given string and k will in the range [1, 10000]
本题是将字符串中的每2k个字符的前k个进行反转,后k个保持不变,如果最后剩下的不足k个则全部翻转,大于等于k个则将前k个反转。可以使用上面的双指针法来解决此题,先看我的解法:
//35%
public static String reverseStr(String s, int k) {
char [] res = s.toCharArray();
int n = s.length()/(2*k), i;
//取前面2k*n个进行反转
for(i=0; i<n; i++){
int left=i*2*k, right=left+k-1;
while(left < right){
char tmp = res[left];
res[left] = res[right];
res[right] = tmp;
left ++;
right --;
}
}
//对最后剩余的进行反转,right设置为k和剩余字符串的较小值
int left=i*2*k, right=Math.min(left+k-1, s.length()-1);
while(left < right){
char tmp = res[left];
res[left] = res[right];
res[right] = tmp;
left ++;
right --;
}
return new String(res);
}
其实仔细一想上面的代码是可以进行简化的,可以把后面的判断语句也融合到前面的循环当中,
//44%
public String reverseStr1(String s, int k) {
char[] arr = s.toCharArray();
int n = arr.length;
int i = 0;
while(i < n) {
int j = Math.min(i + k - 1, n - 1);
swap(arr, i, j);
i += 2 * k;
}
return String.valueOf(arr);
}
private void swap(char[] arr, int l, int r) {
while (l < r) {
char temp = arr[l];
arr[l++] = arr[r];
arr[r--] = temp;
}
}
然后在理清反转关系之后我们还可以使用StringBuilder内置的insert函数进行简化反转操作:
//68%
public String reverseStr2(String s, int k) {
StringBuilder res = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (i % (2 * k) < k) res.insert(i - i % (2 * k), s.charAt(i));
else res.append(s.charAt(i));
}
return res.toString();
}
接下来看最后一道题目:
Write a function that takes a string as input and reverse only the vowels of a string.
Example 1:
Given s = "hello", return "holle".
Example 2:
Given s = "leetcode", return "leotcede".
Note:
The vowels does not include the letter "y".
只反转字符串中的元音“aeiouAEIOU”,有下面三种方法,思路是一样的,都是双指针法,从两侧找元音然后翻转,只是判断元音的数据结构不同,代码的效率也有很大差异,从中我们可以得到下面的结论:
字符串的contains函数效率没有Set效率高,但是这种数据结构的效率都远低于switch语句来的简单方便
//18%,使用字符串存储元音,然后使用contains函数判断
public String reverseVowels(String s) {
if(s == null || s.length()==0) return s;
String vowels = "aeiouAEIOU";
char[] chars = s.toCharArray();
int start = 0;
int end = s.length()-1;
while(start<end){
while(start<end && !vowels.contains(chars[start]+"")){
start++;
}
while(start<end && !vowels.contains(chars[end]+"")){
end--;
}
char temp = chars[start];
chars[start] = chars[end];
chars[end] = temp;
start++;
end--;
}
return new String(chars);
}
//55%,使用set存储元音,然后使用contains()函数判断
public String reverseVowels1(String s) {
char[] list=s.toCharArray();
Set<Character> set=new HashSet<>();
set.add('a');
set.add('e');
set.add('i');
set.add('o');
set.add('u');
set.add('A');
set.add('E');
set.add('I');
set.add('O');
set.add('U');
for (int i=0, j=list.length-1; i<j; ) {
if (!set.contains(list[i])) {
i++;
continue;
}
if (!set.contains(list[j])) {
j--;
continue;
}
char temp=list[i];
list[i]=list[j];
list[j]=temp;
i++;
j--;
}
return String.valueOf(list);
}
public static boolean isVowel(char a){
switch(a){
case ('a') : return true;
case ('e') : return true;
case ('i') : return true;
case ('o') : return true;
case ('u') : return true;
case ('A') : return true;
case ('E') : return true;
case ('I') : return true;
case ('O') : return true;
case ('U') : return true;
default : return false;
}
}
//99%,直接使用switch语句判断是否为元音
public static String reverseVowels2(String s) {
if (s.length()<2) return s;
char[] tab = s.toCharArray();
int j = tab.length - 1;
int i = 0;
while( i < j ) {
if (!isVowel(tab[i]))
i++;
else {
while (j!=i && !isVowel(tab[j]))
j--;
char temp = tab[i];
tab[i] = tab[j];
tab[j] = temp;
i++;
j--;
}
}
return new String(tab);
}