题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。
示例:
输入: “the sky is blue”
输出: “blue is sky the”
输入: " hello world! "
输出: “world! hello” 解释:
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
输入: “a good example”
输出: “example good a” 解释:
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
解题思路:
因为传过来的字符串的头尾可能含有空格,所以我们可以先把头尾的空格去掉。之后
1、遍历字符串中空格的索引 index(找到空格就说明,此时0到index-1位置刚好是一个完整的单词)
2、我们在这个单词前面加上一个空格,并将这个其放到StringBuilder的最前面。
3、我们让传过来的字符串取他本身从index+1到结尾的子串,并去掉头尾的空格(防止有多空格的情况导致结果有偏差)
4、重复1——3步骤,直到字串中不含任何空格。此时我们传过来的字符串刚好剩下最后一个单词。
5、将最后的单词插入到StringBuilder的最前面。
6、将StringBuilder转换为String并返回。
class Solution {
public String reverseWords(String s) {
StringBuilder builder = new StringBuilder();
//去掉头尾空格
s = s.trim();
//从头到尾找单词(遇到空格表示单词结束)
while(s.indexOf(" ") > 0){
int index = s.indexOf(" ");
//每次找到一个就插入到builder的头部,并在单词前面加一个空格
builder.insert(0, " "+s.substring(0, index));
s = s.substring(index+1).trim();
}
//最后会剩下一个单词,我们直接将它添加到builder中即可
builder.insert(0, s);
return builder.toString();
}
}
力扣战绩:
还有另一种使用双指针的解题思路:
首先,我们把s头尾的空格去掉。
然后我们让i和j都等于s此时的长度-1。(指针同时指向s的末端)然后我们从末尾开始遍历s,直到 i 小于0。
遍历过程(结束条件是i < 0):
1、判断第 i 位是不是空格,如果不是,那么 i 自减1
2、当 i 等于空格的时候,就说明此时 i+1 到 j 位刚好是一个完整的单词,我们将其末尾加上空格后添加到builder中。
3、我们继续让 i 自减1, 直到他当前节点不是空格
4、让 j 等于此时的 i (也就是目前要遍历的单词的末尾),回到遍历条件
将builder转换为字符串并把头尾的空格去掉后返回。
class Solution {
public String reverseWords(String s) {
s = s.trim(); // 删除首尾空格
int j = s.length() - 1, i = j;
StringBuilder builder = new StringBuilder();
while(i >= 0) {
while(i >= 0 && s.charAt(i) != ' ') i--; // 搜索首个空格
builder.append(s.substring(i + 1, j + 1) + " "); // 添加单词
while(i >= 0 && s.charAt(i) == ' ') i--; // 跳过单词间空格
j = i; // j 指向下个单词的尾字符
}
return builder.toString().trim(); // 转化为字符串并返回
}
}
力扣战绩: