https://leetcode-cn.com/problems/reverse-words-in-a-string/
class Solution {
public String reverseWords(String s) {
char[] arr = s.toCharArray();
reverse(arr, 0, arr.length - 1);
StringBuffer res = new StringBuffer();
int l = 0, r = arr.length - 1;
//先把两端的空格收缩掉,记录l和r
while(l < r){
if(arr[l] == ' ') l++;
if(arr[r] == ' ') r--;
if(arr[l] != ' ' && arr[r] != ' ') break;
}
int flag = l, L = l,R;
//对每个单词进行翻转,并且加入到res里去,单词之间只加一个空格,多余空格用while循环过滤掉
while(flag < r) {
if(arr[flag] == ' ') {
R = flag - 1;
reverse(arr,L,R);
res.append(new String(arr).substring(L,R + 1));
res.append(' ');
while(arr[flag] == ' ') flag++;
L = flag;
}else {
flag++;
}
}
//上面的循环漏了最后一个单词,再补上
reverse(arr,L,r);
res.append(new String(arr).substring(L,r + 1));
return res.toString();
}
public void reverse(char[] a, int l, int r) {
char temp;
while(l < r){
temp = a[l];
a[l] = a[r];
a[r] = temp;
l++;
r--;
}
}
}
这个方法的劣势在于,每次都要new String整个arr数组,再取substring,因为arr数组每翻转一个单词都在变化,考虑换成stringbuilder进行操作,不用一直创建String空间。
class Solution {
public String reverseWords(String s) {
StringBuilder arr = makearr(s);
reverse(arr, 0, arr.length() - 1);
reverseEachword(arr);
return arr.toString();
}
public void reverseEachword(StringBuilder s) {
int n = s.length();
int start = 0, end = 0;
//遍历所有单词
while(start < n) {
//找到单词末尾,这里注意 end < n而不是end < n - 1,因为end可以取到n - 1
while(end < n && s.charAt(end) != ' ') end++;
reverse(s, start, end - 1);
//翻转后寻找下一个单词
start = end + 1;
end++;
}
}
public StringBuilder makearr(String s){
int l = 0, r = s.length() - 1;
StringBuilder ans = new StringBuilder();
char[] arr = s.toCharArray();
int flag = 0;
//先把两端的空格收缩掉,记录l和r
while(l < r){
if(arr[l] == ' ') l++;
if(arr[r] == ' ') r--;
if(arr[l] != ' ' && arr[r] != ' ') break;
}
//过滤中间的多余空格
for(int i = l;i <= r;) {
if(arr[i] != ' ') {
ans.append(arr[i++]);
}else {
ans.append(arr[i]);
while(arr[i] == ' ') i++;
}
}
return ans;
}
public void reverse(StringBuilder a, int left, int right) {
char temp;
int l = left, r = right;
while(l < r){
temp = a.charAt(l);
a.setCharAt(l++, a.charAt(r));
a.setCharAt(r--, temp);
}
}
}