給你一個字符串 s 阶剑,請你反轉(zhuǎn)字符串中 單詞 的順序(單詞本身不反轉(zhuǎn),單詞間的反轉(zhuǎn))危号。
單詞 是由非空格字符組成的字符串牧愁。s 中使用至少一個空格將字符串中的 單詞 分隔開。
返回 單詞 順序顛倒且 單詞 之間用單個空格連接的結(jié)果字符串外莲。
注意:輸入字符串 s中可能會存在前導(dǎo)空格猪半、尾隨空格或者單詞間的多個空格。返回的結(jié)果字符串中偷线,單詞間應(yīng)當(dāng)僅用單個空格分隔磨确,且不包含任何額外的空格。
● 進階:嘗試使用O(1)額外空間復(fù)雜度的原地解法声邦。
解題思路:
(1) 最簡單的想法就是:先對字符串去除前后空格,然后使用一個StringBuilder對象(sb)歇式,從后往前遍歷String,找到一個單詞(雙指針劃定)后就追加到sb中胡野。
class Solution {
public String reverseWords(String s) {
s = s.trim();
StringBuilder sb = new StringBuilder();
int i = s.length()-1;
int j = i;
while(i >= 0){
// 找下一個單詞的末尾
while(s.charAt(i) == ' ') i--;
j = i;
// 找下一個單詞的頭
while((i-1) >= 0 && s.charAt(i-1) != ' ') i--;
sb.append(s.substring(i, j+1));
sb.append(" ");
i--;
}
return sb.substring(0, sb.length()-1).toString();
}
}
(2) 進階的解法:【不使用任何庫函數(shù)的基礎(chǔ)上】消除多余空格+整體反轉(zhuǎn)+單詞反轉(zhuǎn)材失。?
● 消除多余空格:同向雙指針×蚨梗【類似:代碼隨想錄-移除元素】
● 整體反轉(zhuǎn):相向雙指針【類似:代碼隨想錄-反轉(zhuǎn)字符串】
● 單詞反轉(zhuǎn):(同整體反轉(zhuǎn)龙巨,這里是局部反轉(zhuǎn)) 相向雙指針
class Solution {
public String reverseWords(String s) {
// 先將String轉(zhuǎn)化成char[]
char[] s_char = s.toCharArray();
// 1笼呆、消除多余空格
int i = 0;
int j = 0;
while(j < s_char.length){
if(s_char[j] != ' ') s_char[i++] = s_char[j++];
else{
// 遇到空格了,找到最右邊的空格
while((j+1) < s_char.length && s_char[j] == s_char[j+1]) j++;
if(j == s_char.length-1) break; // 末尾的空格
if(i > 0) s_char[i++] = s_char[j++]; // 中間的空格
else j++; // 開頭的空格
}
}
// 此時i就是有效的s_char長度
int len = i;
j = i - 1;
i = 0;
// 2旨别、利用雙指針诗赌,將整個字符數(shù)組反轉(zhuǎn)
reverseArrayByIndex(s_char, i, j);
// 3、找到每個單詞進行反轉(zhuǎn)
i = 0;
j = 0;
while(j < len){
// 找到單詞的尾
while((j+1) < len && s_char[j+1] != ' ') j++;
reverseArrayByIndex(s_char, i, j);
i = j + 2;
j = i;
}
return new String(s_char).substring(0, len);
}
public void reverseArrayByIndex(char[] arr, int i, int j){
while(i < j){
char c = arr[i];
arr[i] = arr[j];
arr[j] = c;
i++;
j--;
}
}
}