思路 TC O(N), SC O(N)
步骤
- 去除多余空格:
- 两端
- 中间连续两个空格
- 翻转整个字符串
- 逐个翻转单词
简洁
class Solution {
public String reverseWords(String s) {
String[] words = s.trim().split(" ");
StringBuilder result = new StringBuilder();
for (int i = words.length - 1; i >= 0; i--) {
if (!words[i].isEmpty())
result.append(words[i]).append(" ");
}
return result.toString().trim();
}
}
好写法
- 没有用到
trim(), reverse(),只用了sb.setCharAt().
class Solution {
public String reverseWords(String s) {
StringBuffer sb = new StringBuffer(s);
sb = trimSpace(sb.toString()); //去除无效空格
reverse(sb, 0, sb.length() - 1); // 整个翻转
// 翻转内部单词
int pre = 0;
for (int i = 0; i <= sb.length(); i++) {
if (i == sb.length() || sb.charAt(i) == ' ') { // 注意最后一个单词的翻转
reverse(sb, pre, i - 1);
pre = i + 1;
}
}
return sb.toString();
}
// 翻转从start到end的字符串(包含strat end)
public void reverse(StringBuffer sb, int start, int end) {
int i = start, j = end;
while (i < j) {
char tmp = sb.charAt(i);
sb.setCharAt(i, sb.charAt(j));
sb.setCharAt(j, tmp);
i++;
j--;
}
}
// 去除字符串两端空格 和 中间多余空格,返回一个新sb
public StringBuffer trimSpace(String str) {
StringBuffer sb = new StringBuffer();
int m = 0, n = str.length() - 1;
//两端遇到空格,直接跳过
while (str.charAt(m) == ' ') {
m++;
}
while (str.charAt(n) == ' ') {
n--;
}
//去除中间的多余空格,追加到新sb上
for (int i = m; i <= n; i++) {
if (str.charAt(i) == ' ' && str.charAt(i + 1) == ' ') {
continue;
} else {
sb.append(str.charAt(i));
}
}
return sb;
}
}
第一次写的垃圾写法
class Solution {
public String reverseWords(String s) {
StringBuffer sb = new StringBuffer(s.trim());//去除两端空格
sb.reverse();
//去除中间多余空格,开了一个新sb,把不含多余空格的string转移过去
StringBuffer rev = new StringBuffer();
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) != ' ') {
rev.append(sb.charAt(i));
} else if (sb.charAt(i) == ' ' && sb.charAt(i + 1) != ' ') {
rev.append(' ');
}
}
//初始化双指针
int start = 0;
int end = rev.length();
//翻转每个单词
for (int i = 0; i < rev.length(); i++) {
if (rev.charAt(i) == ' ' || i == rev.length() - 1) {//最后一个单词特判
end = i == rev.length() - 1 ? i : i - 1;//最后一个单词特判
while (start <= end) {//每个单词中,双指针swap
char tmp = rev.charAt(end);
rev.setCharAt(end, rev.charAt(start));
rev.setCharAt(start, tmp);
start++;
end--;
}
start = i + 1;//更新下一个单词的start, 为空格后一位
}
}
return rev.toString();
}
}