反转字符串中的元音字母
题目指路
题目描述:
编写一个函数,以字符串作为输入,反转该字符串中的元音字母。
示例 1:
输入:“hello”
输出:“holle”
示例 2:
输入:“leetcode”
输出:“leotcede”
思路一(比较菜的双指针):
两边的指针逐渐向中间逼近,直到两指针重合跳出循环。
两指针移动的时候分为以下几种情况:
1.当左指针没有指向元音字母,右指针也没有指向元音字母时,这种情况一般多见于初始状态(当然,初始状态时也可能有指针指向元音字母的情况),此时,左指针向右移动;
2.当左指针指向元音字母,右指针没有指向元音字母时,左指针停止移动,右指针向左移动;
3.当左指针和右指针同时指向元音字母时,两元音字母执行交换操作,交换之后,左指针向右移动,此时还需要先检查移动后的左指针与右指针有没有重合,若重合则跳出循环;若没有重合,右指针也向左移动;
4.当左指针没有指向元音字母,右指针指向元音字母时,右指针停止移动,左指针向右移动;
所有的前提还得判断字符串不是“”。
class Solution {
public String reverseVowels(String s) {
if(s.equals("")){
return s;
}
String[] str=s.split("");
int i=0;
int j=s.length()-1;
while(i!=j){
if(isVowel(str[i])&&isVowel(str[j])){
String temp=str[j];
str[j]=str[i];
str[i]=temp;
i++;
if(i==j){
break;
}
j--;
continue;
}else if(isVowel(str[i])){
j--;
continue;
}else if(isVowel(str[j])){
i++;
continue;
}else{
i++;
continue;
}
}
StringBuffer sb = new StringBuffer();
for(int k=0;k<str.length;k++){
sb.append(str[k]);
}
return sb.toString();
}
public boolean isVowel(String c){
if(c.equals("a")||c.equals("e")||c.equals("i")||c.equals("o")||c.equals("u")||
c.equals("A")||c.equals("E")||c.equals("I")||c.equals("O")||c.equals("U")){
return true;
}else{
return false;
}
}
}
注:将字符串转换为字符串数组
String[] str=s.split("");
这块可以稍微优化一下
后图将循环条件修改了一下。
以上优化可以诞生出思路二(稍微优化一点的双指针):
为了降低时间复杂度,可以适当将移动一个指针变为同时移动两个指针。以下思路中,将符合最后一个判断条件的情况改为同时移动两个指针。
class Solution {
public String reverseVowels(String s) {
if(s.equals("")){
return s;
}
String[] str=s.split("");
int i=0;
int j=s.length()-1;
while(i<j){
if(isVowel(str[i])&&isVowel(str[j])){
String temp=str[j];
str[j]=str[i];
str[i]=temp;
i++;
j--;
continue;
}else if(isVowel(str[i])){
j--;
continue;
}else if(isVowel(str[j])){
i++;
continue;
}else{
i++;
j--;
continue;
}
}
StringBuffer sb = new StringBuffer();
for(int k=0;k<str.length;k++){
sb.append(str[k]);
}
return sb.toString();
}
public boolean isVowel(String c){
if(c.equals("a")||c.equals("e")||c.equals("i")||c.equals("o")||c.equals("u")||
c.equals("A")||c.equals("E")||c.equals("I")||c.equals("O")||c.equals("U")){
return true;
}else{
return false;
}
}
}
思路三:
简化了一下判断条件
1.当左指针指向的不是元音字母时,左指针向右移动;
2.当右指针指向的不是元音字母时,右指针向左移动;
3.当以上两个条件都不满足时,即左指针和右指针指向的都是元音字母,则交换位置,左指针向右移动,右指针向左移动;
class Solution {
public String reverseVowels(String s) {
String[] str=s.split("");
int i=0;
int j=s.length()-1;
while(i<j){
if(!isVowel(str[i])){
i++;
continue;
}
if(!isVowel(str[j])){
j--;
continue;
}
String temp=str[j];
str[j]=str[i];
str[i]=temp;
i++;
j--;
}
StringBuffer sb = new StringBuffer();
for(int k=0;k<str.length;k++){
sb.append(str[k]);
}
return sb.toString();
}
public boolean isVowel(String c){
if(c.equals("a")||c.equals("e")||c.equals("i")||c.equals("o")||c.equals("u")||
c.equals("A")||c.equals("E")||c.equals("I")||c.equals("O")||c.equals("U")){
return true;
}else{
return false;
}
}
}
思路四:
前面几种思路一直困扰的一个问题是,转换成string类型的数组比转换成char型的数组慢,所以我们这一次尝试转换成char类型的数组,还是采用思路三中双指针的方法。
class Solution {
public String reverseVowels(String s) {
char[] str = s.toCharArray();
int i=0;
int j=s.length()-1;
while(i<j){
if(!isVowel(str[i])){
i++;
continue;
}
if(!isVowel(str[j])){
j--;
continue;
}
char temp=str[j];
str[j]=str[i];
str[i]=temp;
i++;
j--;
}
StringBuffer sb = new StringBuffer();
for(int k=0;k<str.length;k++){
sb.append(str[k]);
}
return sb.toString();
}
public boolean isVowel(char c){
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||
c=='A'||c=='E'||c=='I'||c=='O'||c=='U'){
return true;
}else{
return false;
}
}
}
注:将字符串转换为char型数组
char[] str = s.toCharArray();
再将下图的这一部分进行修改
变为以下代码
class Solution {
public String reverseVowels(String s) {
char[] str = s.toCharArray();
int i=0;
int j=s.length()-1;
while(i<j){
if(!isVowel(str[i])){
i++;
continue;
}
if(!isVowel(str[j])){
j--;
continue;
}
char temp=str[j];
str[j]=str[i];
str[i]=temp;
i++;
j--;
}
String ss=new String();
ss=String.valueOf(str);
return ss;
}
public boolean isVowel(char c){
if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||
c=='A'||c=='E'||c=='I'||c=='O'||c=='U'){
return true;
}else{
return false;
}
}
}