給你一個字符串?
s
?,請你反轉字符串中?單詞?的順序。單詞?是由非空格字符組成的字符串。
s
?中使用至少一個空格將字符串中的?單詞?分隔開。返回?單詞?順序顛倒且?單詞?之間用單個空格連接的結果字符串。
注意:輸入字符串?
s
中可能會存在前導空格、尾隨空格或者單詞間的多個空格。返回的結果字符串中,單詞間應當僅用單個空格分隔,且不包含任何額外的空格。輸入:s = "the sky is blue" 輸出: "blue is sky the"
? ? ? ?看到圖片中的操作,我覺得我們的第一印象應該是先用Stirng()中的方法tirm()將字符串兩邊的空白字符給去掉,然后再用toCharArray()方法將字符轉換為char數組,然后再倒敘遍歷數組填充到一個新的字符串中去,這道題就結束了,可是真的是這樣么?
public String reverseWords(String s) {if(s.length()==0){return "";}//去掉兩邊的空格s=s.trim();//trim函數需要返回一個新的字符串,這里千萬別忘記//根據“”進行分割String[] str=s.split(" ");String s1="";for (int i = str.length-1; i>=0; i--) {if(i==0){s1+=str[i];}else{s1+=str[i]+" ";}}s1=s1.trim();return s1;}
? ? ? ?原來這個題目中測試案例字符串中中間間隔的不一定只有一個空字符串,甚至有多個空字符串,所以我們就要對正則表達式中的規則進行一點改變
String[] str=s.split("\\s+");//匹配多個空白字符
?過程是痛苦的但是結局確實好的
接下來給大家介紹一種比較高效的方法解決本題(雙指針)
? ? ? ?這時候有很多人就會要問了?如果遍歷字符串的話,每個指針只能指向一個字符,反轉的話只能使一個字符進行翻轉,怎么樣才可以做到對整個單詞進行翻轉呢?一個指針當然只可以指向一個字符了,但是兩個指針就可以確定一個單詞,我們可以尋找空格的位置去確定我們單詞的位置
?我們做的前提得是兩邊沒有空格的字符串,所以我們首先用String類中的trim()函數進行去除
//去掉兩邊的空格String s1=s.trim();
在操作字符串的時候,我們經常將String類型轉換為StringBuilder類型進行字符串的操作
StringBuilder res=new StringBuilder();
? ? ? ?因為我們需要進行對原字符串進行反轉,干脆我們一開始就從最后面開始,這樣可以省去一次翻轉的時間
int i=s1.length()-1;
int j=i;
while(i>=0){...}
因為我們的字符串兩邊沒有空格,所以我們依靠中間兩個單詞之間的空格來確定單詞的界限
while(i>=0&&s1.charAt(i)!=' '){i--;}
? ? ? ?因為我們要將這個字符串截取出來,將其加入到StringBuilder中,substring(start,end)函數,是一個左閉右開的取值范圍
res.append(s1.substring(i+1,j+1)+" ");
如果兩個單詞間隔許多空格的話,我們需要跳過這些空格,去尋找下一個單詞的末尾字符
while(i>=0&&s1.charAt(i)==' '){i--;}
同步j指針,說明找到了一個新的單詞,重復上面的步驟
j=i;
?源代碼如下:
public String reverseWords(String s) {if(s.length()==0){return "";}//去掉兩邊的空格String s1=s.trim();StringBuilder res=new StringBuilder();int i=s1.length()-1;int j=i;while(i>=0){while(i>=0&&s1.charAt(i)!=' ')i--;res.append(s1.substring(i+1,j+1)+" ");while(i>=0&&s1.charAt(i)==' ')i--;j=i;}return res.toString().trim();}