題解一
思路
最開始的想法是把一個字符串分為字符串數組,但是不知道一共有幾個單詞(當時沒想起來split()),所以選擇了用ArrayList儲存字符串,在輸出時沒有考慮ArrayList可以存儲空字符串,所以最開始的輸出不正確,改進之后正確了。
代碼
class Solution {public String reverseWords(String s) {List<String> list = new ArrayList<>();int tag = 0;for(int i = 0; i < s.length(); i++){if(i == s.length() - 1 && s.charAt(i) != ' '){list.add(s.substring(tag));}if(s.charAt(i) == ' '){list.add(s.substring(tag,i));tag = i + 1;}}String res = "";for(int i = list.size() - 1; i >= 0; i--){if(!list.get(i).isEmpty()) res += list.get(i) + " ";}res = res.trim();return res;}
}
總結
對字符串還是不夠熟練,有好多方法在用的時候想不起來
題解二?
思路
首先用trim()方法將s前后的空格消掉,然后再用split()函數識別多個連續空格,在一個或多個連續空格處分開,用字符串數組存儲,再用Collections.reverse()進行顛倒,然后再用join()函數用空格做間隔輸出。
代碼
class Solution {public String reverseWords(String s) {String[] str = s.trim().split("\\s+");List<String> list = Arrays.asList(str);Collections.reverse(list);return String.join(" ",list);}
}
總結
用到很多String的內置函數,非常簡潔。
也學習到了很多新知識,比如trim()、split()、asList()、Collections類、\\s+正則表達式。其中trim()和split()就不多說了
asList()
通過asList()得到的列表,不能進行add()和remove()操作,但可以進行set()操作,這也是為什么雖然這個方法也新建了動態數組,但是并沒有增加空間復雜度(是String[]增加了這個方法的空間復雜度)。Arrays.asList() 返回的 List 實際上是一個基于數組的視圖(view),即它并沒有復制數組的內容,而是直接操作原數組的引用。這也是為什么他不能進行add()和remove()操作,因為這里的List是固定大小的,
\\s+
第一次使用正則表達式,用的時候就搞不懂這里為什么是\\雙反斜杠,說說我自己的理解。\n,\t 這種\是轉義符。\\s里的第一個\代表轉義符,告訴Java這里要轉義,而第二個\是正則表達式里的\,和s是一起的,\s表示正則中的空白字符。而\n,\t并不是正則表達式,所以不需要用\\
題解三
思路
首先將整個字符串變成“標準”字符串(即前后無空格,相鄰單詞間只有一個空格),然后將整個字符串倒轉,最后分別將字符串的每個單詞再分別倒轉。
代碼
class Solution {public String reverseWords(String s) {StringBuilder sb = removeSpace(s);reverseString(sb, 0, sb.length()-1);reverseEachWord(sb);return sb.toString();}
//1.除去多余空白符public StringBuilder removeSpace(String s){int start = 0;int end = s.length() - 1;StringBuilder sb = new StringBuilder();while(s.charAt(start) == ' '){start++;}while(s.charAt(end) == ' '){end--;}while(start <= end){if(s.charAt(start) != ' ' || sb.charAt(sb.length() - 1) != ' '){sb.append(s.charAt(start));}start++;}return sb;}
//2.倒轉整個字符串public void reverseString(StringBuilder sb, int start, int end){while(start <= end){char temp = sb.charAt(start);sb.setCharAt(start, sb.charAt(end));sb.setCharAt(end, temp);start++;end--;}}
//3.分別倒轉字符串中的每個單詞public void reverseEachWord(StringBuilder sb){int start = 0;int end = 1;int length = sb.length();while(start < length){while(end < length && sb.charAt(end) != ' '){end++;}reverseString(sb, start, end - 1);start = end + 1;end = start + 1;}}
}
總結
最后這種題解,只需新建一個新的StringBuilder類型對象,然后在該StringBuilder進行修改,不需要額外開辟數組或集合,空間復雜度低。
就是太復雜了!!學習過后復現都很難!!!
番外:
今天用了StringBuilder,昨天使用了StringBuffer,二者的區別是StringBuffer的方法使用synchronized修飾,具有線程安全的特點,但是相應的響應速度就更慢一些,看在哪里使用