剑指 Offer 58 - I. 翻转单词顺序 - 力扣(LeetCode) (leetcode-cn.com)
输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。
方式一:
class Solution {
public String reverseWords(String s) {
//s=" the sky is blue "
//除去开头和结尾的空白字符s="the sky is blue"
s = s.trim();
// 正则匹配连续的空白字符作为分隔符分割
//split返回的是String[]类型
List<String> wordlist = Arrays.asList(s.split("\\s+"));
// wordlist=["the","sky","is","blue"]
Collections.reverse(wordlist);
// wordlist=["blue","is","sky","the"]
return String.join(" ",wordlist);
}
}
方式二:先去掉所有多于的空格,然后将整个字符串反转,最后再将每个单词反转
class Solution {
public String reverseWords(String s) {
//去掉多于的空格
StringBuilder sb = trimSpace(s);
// 翻转字符串
reverse(sb,0,sb.length()-1);
// 翻转每个单词
reverseEachWord(sb);
return sb.toString();
}
public StringBuilder trimSpace(String s){
int left = 0, right = s.length()-1;
// 去掉字符串开头的空白字符
while(left <= right && s.charAt(left) == ' '){
left++;
}
// 去掉字符串末尾的空白字符
while(left <= right && s.charAt(right) == ' '){
right--;
}
// 将字符串间多余的空白字符去除
StringBuilder sb = new StringBuilder();
while(left <= right){
char c = s.charAt(left++);
if(c != ' '){
sb.append(c);
}else if(sb.charAt(sb.length()-1) != ' '){
//如果s中连续2个空格,第一个空格放到sb中后,第二个空格就不用了
sb.append(c);
}
}
return sb;
}
public void reverse(StringBuilder sb, int left, int right){
while(left < right){
char ch = sb.charAt(left);
sb.setCharAt(left++, sb.charAt(right));
sb.setCharAt(right--, ch);
}
}
public void reverseEachWord(StringBuilder sb){
int n = sb.length();
int left = 0, right = 0;
while(left < n){
// 循环至单词的末尾
while(right < n && sb.charAt(right) != ' '){
right++;
}
// 翻转单词
reverse(sb,left,right-1);
// 更新left,去找下一个单词
left = right+1;
right++;
}
}
}