1. 程式人生 > 其它 >力扣151(java)-顛倒字串中的單詞(中等)

力扣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 class
Solution { 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

7.toString()方法將物件轉換為字串。