力扣151(java)-顛倒字串中的單詞(中等)
題目:
給你一個字串 s ,顛倒字串中 單詞 的順序。
單詞 是由非空格字元組成的字串。s 中使用至少一個空格將字串中的 單詞 分隔開。
返回 單詞 順序顛倒且 單詞 之間用單個空格連線的結果字串。
注意:輸入字串 s中可能會存在前導空格、尾隨空格或者單詞間的多個空格。返回的結果字串中,單詞間應當僅用單個空格分隔,且不包含任何額外的空格。
示例 1:
輸入:s = "the sky is blue"
輸出:"blue is sky the"
示例 2:
輸入:s = " hello world "
輸出:"world hello"
解釋:顛倒後的字串中不能存在前導空格和尾隨空格。
示例 3:
輸入:s = "a good example"
輸出:"example good a"
解釋:如果兩個單詞間有多餘的空格,顛倒後的字串需要將單詞間的空格減少到僅有一個。
提示:
1 <= s.length <= 104
s 包含英文大小寫字母、數字和空格 ' '
s 中 至少存在一個 單詞
進階:如果字串在你使用的程式語言中是一種可變資料型別,請嘗試使用 O(1) 額外空間複雜度的 原地 解法。
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/reverse-words-in-a-string
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
解題思路:
一、暴力求解
1.先使用trim()減去字串兩端的空格;
2.使用split()將字串按空格分割成字串陣列;
3.使用reverse()將字串陣列進行反轉;
4.最後用join()將字串陣列拼接成一個字串。
程式碼:
二、雙指標
1.將字串轉換成字元陣列;
2.設定兩個指標left和right分別指向陣列的初始位置和結束位置,裁剪掉兩端的空格;
3.藉助index指標,從right位置開始向左遍歷,直到遇到空格,然後在[index+1, right]範圍內遍歷字元將字元放在stringBuilder中,並新增空格;
4.然後跳過中間連續的空格,當index有字元時,代表遇到下一個字串的結束位置,改變right的值,index繼續向左遍歷,直到遇到空格,後面與步驟3一致進行新增;
5.返回string型別的字串。
程式碼:
1 classSolution { 2 public String reverseWords(String s) { 3 char[] s1 = s.toCharArray(); 4 StringBuilder s2 = new StringBuilder(); 5 int left = 0, right = s.length()-1; 6 //去掉字串左右兩端的空白 7 while(s1[left] == ' ') { 8 left++; 9 } 10 while(s1[right] == ' ') { 11 right--; 12 } 13 //新增單詞 14 while (left <= right){ 15 int index = right; 16 while(index >= left && s1[index] != ' ') { 17 index--; 18 } 19 //當index所指為空格時,後面一位才是當前單詞的初始位置 20 for(int i = index+1; i <= right; i++){ 21 s2.append(s1[i]); 22 } 23 //不是最後一個單詞時都需要新增空格 24 if(index > left) s2.append(' '); 25 //跳過中間的空格,開始尋找下一個單詞的位置 26 while(index >= left && s1[index] == ' '){ 27 index --; 28 } 29 right = index; 30 } 31 return s2.toString(); 32 } 33 }
小知識:
1.將陣列轉化成List集合的方法,此方法得到的list長度是不可變的
List<String> list = Arrays.asList("aa","bb","cc");
(1)該方法適用於物件型資料的陣列(String、Integer...)
物件型別(String型)的陣列陣列使用asList(),正常 1 String[]strings = {f"aa","bb","cc"}; 2 List<String> stringList = Arrays.asList(strings); //String型別陣列使用asList(),正常:aa bb cc
(2)該方法不建議使用於基本資料型別的陣列(byte,short,int,long,float,double,boolean)
基本資料型別的陣列使用asList(),出錯 1 int[] ints = new int[]{1,2,3}; 2 List intList = Arrays.asList(ints); //基本資料型別的陣列使用asList(),出錯(輸出的是一個引用,把ints當成一個元素了):[I@1540e19d這樣遍歷才能正確輸出: 1 2 3
(3)該方法將陣列與List列表連結起來:當更新其一個時,另一個自動更新
(4)不支援add()、remove()、clear()等方法
2.split("\\s+")和split("+"):
\s 表示:匹配任何空白字元,包括空格、製表符、換頁符等等。等價於[ \f\n\r\t\v]
+ 表示:匹配前面的子表示式一次或多次。
\s+ 表示:以空格、換行符、回車為分割線,相鄰的多個空格、換行符、回車仍然視為只有一個,分隔後返回字元陣列
3.Collections類是集合類的一個工具類其中提供了一系列靜態方法,用於對集合中元素進行排序、搜尋以及執行緒安全等各種操作,常用方法:
public class test{ public static void main(String[] args){ List list = new ArrayList(); list.add("b"); list.add("s"); list.add("t"); list.add("a"); //1.對集合進行排序--[a,b,s,t] Collections.sort(list); System.out.println(list); //2.對集合進行隨機排序--[s,a,t,b] Collections.shuffle(list); System.out.println(list); //3.查詢指定集合中的元素,返回所查詢元素的索引--1 int n = Collections.binarySearch(list, "s"); System.out.println(n); //4.反轉集合中的元素--[t,s,b,a] Collections.reverse(list); System.out.println(list); //5.替換某元素,若要替換的值存在返回true,反之返回false --true,[b,s,t,f,p] System.out.println(Collections.replaceAll(list, "a","f p")); //6.集合中的元素向後移m個位置,在後面被遮蓋的元素迴圈到前面來--[a,b,s,t] Collections.rotate(list, 1); System.out.println(list); //7.將集合n中的元素全部賦值到list中,並且覆蓋相應索引的元素--[one, two, three, a] List n = Arrays.asList("one two three".split(" ")); Collections.copy(list, n) System.out.println(list); //8.交換集合中指定元素索引的位置--[b, s, a, t] Collections.swap(list, 2, 3); System.out.println(list); } }
4.Java String join()方法返回一個新字串,該字串具有給定的元素和指定的分隔符。
String.join(CharSequence delimiter,CharSequence... elements)將elements用指定的字串delimeter連線起來
delimiter:與元素連線的連線符
elements:連線的元素
...: 表示可以有一個或多個CharSequence(字元序列)。
注意: join()是靜態方法。您無需建立字串物件即可呼叫此方法。使用類名稱String呼叫該方法。
例如:
String message = String.join("-", "java", "is", "cool"); //返回的是“java-is-cool”
5.char[] s1 = s.toCharArray():將字串s轉換成一個char型別的陣列。
6.在使用無參構造來構造StringBuilder物件:
StringBuilder s2 = new StringBuilder();
Java String、StringBuffer 和 StringBuilder 的區別:
- string字串常量,字串長度不可變,每次對 String 型別進行改變的時候,都會生成一個新的 String 物件,然後將指標指向新的 String 物件,所以經常改變內容的字串最好不要用 String ,因為每次生成物件都會對系統性能產生影響;
- stringBuffer:字串變數(Synchronized,即執行緒安全)。如果要頻繁對字串內容進行修改,出於效率考慮最好使用 StringBuffer,如果想轉成 String 型別,可以呼叫 StringBuffer 的 toString() 方法;
- stringBuilder:字串變數(非執行緒安全)。在內部,StringBuilder 物件被當作是一個包含字元序列的變長陣列,在執行速度方面的比較:StringBuilder > StringBuffer.
使用原則:
- 如果要操作少量的資料用 :String
- 單執行緒操作字串緩衝區 下操作大量資料 : StringBuilder
- 多執行緒操作字串緩衝區 下操作大量資料 : StringBuffer