151.反转字符串中的单词
给你一个字符串 s
,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例 1:
输入:s = "the sky is blue
" 输出:"blue is sky the
"
示例 2:
输入:s = " hello world " 输出:"world hello" 解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:
输入:s = "a good example" 输出:"example good a" 解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
提示:
1 <= s.length <= 104
s
包含英文大小写字母、数字和空格' '
s
中 至少存在一个 单词
思路
最简单的方法就是用封装好的函数split直接写,但是没什么意义
所以想另一种方法,第一步将整个字符串中多余的空格(串首、串尾、连续空格)消除,第二步将整个字符串倒转,第三步将每个单词倒转。
每一步都可以封装一个函数来写
因为String在Java中是一种不可变的数据类型,所以我们使用StringBuilder来进行操作
StringBuilder的常用几种操作:charAt、setCharAt、append
class Solution {
/*
1、去除多余空格
2、反转整个字符串
3、反转每个单词
*/
public String reverseWords(String s) {
StringBuilder sb=removeSpace(s);
reverseString(sb,0,sb.length()-1);
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder removeSpace(String s){
int start=0;
int end=s.length()-1;
//去除前置空格
while(s.charAt(start)==' ')
start++;
//去除后置空格
while(s.charAt(end)==' ')
end--;
StringBuilder sb= new StringBuilder();
while(start<=end){
char c=s.charAt(start);
//如果当前字符不为空格或者上一个字符不为空格则存入sb
if(c!=' '||sb.charAt(sb.length()-1)!=' '){
sb.append(c);
}
start++;
return sb;
}
}
public void reverseString(StringBuilder s,int start,int end){
while(start<end){
char temp=s.charAt(start);
s.setCharAt(start,s.charAt(end));
s.setCharAt(end,temp);
start++;
end--;
}
}
public void reverseEachWord(StringBuilder s){
int start=0;
int end=1;
int n=s.length();
//对每个单词进行调转
while(start<n){
while(s.charAt(end)!=' '&&end<n){
end++;
}
reverseString(s,start,end-1);
start=end+1;
end=start+1;
}
}
}
看了题解之后好像还能用另外的解法,需要用到Deque,又是一个知识盲区
由于双端队列支持从队列头部插入的方法,因此我们可以沿着字符串一个一个单词处理,然后将单词压入队列的头部,再将队列转成字符串即可
class Solution {
public String reverseWords(String s) {
int left = 0, right = s.length() - 1;
// 去掉字符串开头的空白字符
while (left <= right && s.charAt(left) == ' ') {
++left;
}
// 去掉字符串末尾的空白字符
while (left <= right && s.charAt(right) == ' ') {
--right;
}
Deque<String> d = new ArrayDeque<String>();
StringBuilder word = new StringBuilder();
while (left <= right) {
char c = s.charAt(left);
if ((word.length() != 0) && (c == ' ')) {
// 将单词 push 到队列的头部
d.offerFirst(word.toString());
word.setLength(0);
} else if (c != ' ') {
word.append(c);
}
++left;
}
d.offerFirst(word.toString());
return String.join(" ", d);
}
}
总结
这道题算是比较复杂了的,思路需要拓宽一下,StringBuilder和Deque的操作还不够熟悉。