題目以下java
對於字符串的操做一直都是很是重要的,並且有關字符串的題有各類很是奇妙的解法。個人感受是這類題目要是方法或者邏輯不正確而去嘗試暴力解法,能把本身玩死......正則表達式
方法1、利用Split方法數組
用很是簡潔並且容易理解的代碼解決題目,思想是:利用正則表達式的split方法將字符串分解成單詞存放在數組中,而後將數組逆序輸出就ok。什麼是正則表達式?這個均可以寫一本書了,還得慢慢琢磨,先知道Split()方法就行。
app
split() 方法根據匹配給定的正則表達式來拆分字符串,參數爲分隔符,當分隔符中有轉義字符時,要加「\\」在分隔符前面。舉個栗子,若是用「.」做爲分隔符的話,就必須使用String.split("\\.")才能正確分割字符串。ide
而後逆序輸出也不採用傳統的for循環,用Collections.reverse()實現元素順序的反轉。(真的是簡潔起來擋都擋不住系列)時間複雜度爲O(N).
函數
API是這樣寫的:測試
Java實現ui
public class StringReverseBter { public static class Solution { private String reverseWords(String s) { if(s == null || s.length() == 0) return s; /* * @split()正則表達式 * +號表示匹配前面的子表達式一次或屢次(大於等於1次) * e.g.「zo+」能匹配「zo」以及「zoo」,但不能匹配「z」。+等價於{1,}*/ String[] words = s.trim().split(" +"); Collections.reverse(Arrays.asList(words)); //也可使用StringBuilder來處理 StringBuilder sb = new StringBuilder(); for(int i = words.length-1;i >= 0;i--){ sb.append( words[i] + " "); } return sb.toString().trim(); //return String.join(" ", words); } } }
方法二 先將整個字符串的字符反轉,再將單個詞的字符反轉spa
e.g 「the sky is blue」→ 「eulb yks si eht」 → 「blue is sky the」
code
整個解決過程分爲三個部分:字符串反轉、單詞反轉、去多餘的空格。時間複雜度爲O(N)
String.trim()方法的做用是將String全部的前導空白字符和尾部空白字符移除
直接上代碼
package Leetcode; public class StringReverseBter2 { private String Solution(String s){ if(s == null || s.length() < 1) return s; String res; char[] str = s.toCharArray(); int len = s.length(); reverse(str,0,len-1);//reverse the string letter by letter reverseWord(str,len); res = delSpaces(str,len); return res; } /* * reverse the string * */ private void reverse(char[] ch,int i,int j){ while(i < j){ char temp = ch[i]; ch[i++] = ch[j]; ch[j--] = temp; } } /* * reverse the word letter by letter * */ private void reverseWord(char[] ch ,int len){ int i = 0; int j = 0; //e.g "the sky is blue" while(i < len){ while(i < j || i < len && ch[i] == ' ') i++; while(j < i || j < len && ch[j] != ' ') j++; //上面這兩個循環的做用是找到一個單詞的起始和結束位置座標 //找到起始座標i和結束座標j以後利用reverse函數將其反轉 reverse(ch,i,j-1); } } /* * delete the spaces * e.g " the sky is blue" * */ private String delSpaces(char[] ch,int len) { int i = 0; int j = 0; while(i < len) { while(i < len && ch[i] == ' ') i++;//找到空格後第一個字母的起始位置 while(i < len && ch[i] != ' ') ch[j++] = ch[i++]; //把第一個字母放在數組0的位置,並依次日後 while(i < len && ch[i] == ' ') i++;//繼續將全部空格跳過 //上面三個循環結束後數組中存放的字母爲「the」 if(i < len ) ch[j++] = ' ';//在the後面加上一個空格 } return String.valueOf(ch).substring(0,j); //有可能字符串是「the sky is blue 」最後有多個空格,因此直接取0—j //或者能夠用return new String(ch).trim(); } public static void main(String[] args){ String test = " the sky is buleee "; StringReverseBter2 srb2 = new StringReverseBter2(); System.out.println(srb2.Solution(test)); } }
方法3、我第一次嘗試時用的暴力法
這個寫的就很是亂,沒有邏輯,沒有方法,看看就行。放在這裏的緣由是畢竟這也是我辛辛苦苦花時間寫的,仍是值得確定的 >_<
package Leetcode; import java.util.Scanner; public class StringReverse { public static String reverse(String s){ String res = ""; s = s.trim(); int len = s.length(); char[] tmp = new char[len]; //處理輸入全爲空格的狀況 if(s.trim().isEmpty()){ return res; } //字符串處理 int index = 0; for(int i=0 ; i<len ;i++){ tmp[i] = s.charAt(i); if(s.charAt(i) == ' '){ index++; } } String[] word = new String[index+1]; for(int i = 0;i<index+1;i++){ word[i] = ""; } int index1 = 0; for(int i = 0;i<=index;i++){ for(;index1<len;index1++){ if(s.charAt(index1) == ' '){ index1++; break; }else{ word[i] += s.charAt(index1); //word[i] = word[i].trim(); } } } for(int i = index;i >0;i--){ if(word[i] != ""){ res += word[i] + " "; } } return res+word[0]; } public static void main(String[] args){ String test = "the sky is blue"; System.out.println(reverse(test).trim()); } }
測試:
方法一:
方法二:
方法三: