这篇文章记录如何解决力扣第151题:反转字符串中的单词
题目描述
问题分析
通过对题目的理解我们需要解决的问题如下:
- 去除多余空格
- 反转单词
对于问题一:
根据示例,冗余空格存在的位置有三种情况:句子开头、句子结尾、单词之间。
开头和结尾的空格比较好处理:
对于开头的空格,我们只要使用一个 while 循环 + 指针从前往后遍历,遇到非空格停止即可;同理,对于结尾的空格,我们运用相同的方法从后往前遍历即可。
对于中间的冗余空格:
我们可以借助一个辅助空间res,从start位置开始遍历字符串
如果start指向的是字符,则将字符追加到res结尾处;
如果start指向的是空格,则判断res结尾处是否已经含有空格,若无空格则直接将空格追加到res结尾处,若有空格不追加,start++;
一直到start到end的位置。指针移动过程如下:
对于问题二:
问题二的解决方案比较容易想,我们只需先将整个字符串反转,再依次将每个单词反转即可。
字符串的反转可以不用另开辟空间,我们可以借助双指针法,让字符串对称位置的字符交换位置即可,比如字符串 hello world 只需让 h 与 d 交换,e 与 l 交换 ...依次类推。
单词反转的思路与字符串反转一致。
代码实现
这里反转字符串和反转单词共用了同一个函数reverseString() ,在这个函数中,我们指定了两个参数 start 和 end 代表反转的起始、终止位置。这样只需传入需要反转的单词首字母和尾字母在字符串中的位置,以及给定字符串即可完成反转操作。
class Solution {
public String reverseWords(String s) {
StringBuilder sb = new StringBuilder(s);
StringBuilder tmp = removeSpace(sb);
tmp = reverseString(tmp,0,tmp.length()-1);
String res= reverseEachWorld(tmp);
return res;
}
//移除字符中的多余空格
StringBuilder removeSpace(StringBuilder sb){
StringBuilder res = new StringBuilder();
int start = 0,end = sb.length()-1;
while(sb.charAt(start)==' ') start++; //去除开头多余空格
while(sb.charAt(end)==' ') end--; //去除结尾多余空格
while(start<=end){
if(sb.charAt(start)!=' '|| res.charAt(res.length()-1)!=' '){
res.append(sb.charAt(start));
}
start++;
}
return res;
}
//反转字符串操作
StringBuilder reverseString(StringBuilder sb,int start,int end){
while(start<end){
char tmp = sb.charAt(start);
sb.setCharAt(start,sb.charAt(end));
sb.setCharAt(end,tmp);
start++;
end--;
}
return sb;
}
//反转单词操作
String reverseEachWorld(StringBuilder sb){
StringBuilder res = new StringBuilder();
int i=0;
while(i<sb.length()){
int start = i;
int end = i+1;
while((sb.charAt(i)!=' ')&&(i<sb.length())){
i++;
end++;
};
res.append(reverseString(sb,start,end-1));
i++;
}
return res.toString();
}
}
总结
这道题在力扣中属于中等类型,难度不算太高,对我来说的主要难点在于如何去除冗余的空格
若有错误烦请各位大佬批评指正~