其他系列文章導航
Java基礎合集
數據結構與算法合集設計模式合集
多線程合集
分布式合集
ES合集
文章目錄
其他系列文章導航
文章目錄
前言
一、題目描述
二、題解
2.1 方法一:雙指針
2.2 方法二:分割 + 倒序
三、代碼
3.1 方法一:雙指針
3.2 方法二:分割 + 倒序
四、復雜度分析
4.1 方法一:雙指針
4.2 方法二:分割 + 倒序
前言
這是力扣的151題,難度為中等,解題方案有很多種,本文講解我認為最奇妙的兩種。
一、題目描述
給你一個字符串?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)
?額外空間復雜度的?原地?解法。
二、題解
2.1 方法一:雙指針
思路與算法:
- 先去首尾空格。
- 倒序遍歷字符串 s?,記錄單詞左右索引邊界 i?, j 。
- 每確定一個單詞的邊界,則將其添加至單詞列表 res?。
- 最終,將單詞列表拼接為字符串,去掉尾部空格,并返回即可。
2.2 方法二:分割 + 倒序
思路與算法:
以空格為分割符完成字符串分割后,若兩單詞間有 x>1 個空格,則在單詞列表 strs 中,此兩單詞間會多出 x?1 個 “空單詞” (即 "" )。
解決方法:倒序遍歷單詞列表,并將單詞逐個添加至 StringBuilder ,遇到空單詞時跳過。
三、代碼
3.1 方法一:雙指針
Java版本:
class Solution {public String reverseWords(String s) {s = s.trim(); // 刪除首尾空格int j = s.length() - 1, i = j;StringBuilder res = new StringBuilder();while (i >= 0) {while (i >= 0 && s.charAt(i) != ' ') i--; // 搜索首個空格res.append(s.substring(i + 1, j + 1)).append(" "); // 添加單詞while (i >= 0 && s.charAt(i) == ' ') i--; // 跳過單詞間空格j = i; // j 指向下個單詞的尾字符}return res.toString().trim(); // 轉化為字符串并返回}
}
Python版本:?
class Solution:def reverseWords(self, s: str) -> str:s = s.strip() # 刪除首尾空格i = j = len(s) - 1res = []while i >= 0:while i >= 0 and s[i] != ' ': i -= 1 # 搜索首個空格res.append(s[i + 1: j + 1]) # 添加單詞while i >= 0 and s[i] == ' ': i -= 1 # 跳過單詞間空格j = i # j 指向下個單詞的尾字符return ' '.join(res) # 拼接并返回
3.2 方法二:分割 + 倒序
Java版本:
class Solution {public String reverseWords(String s) {String[] split = s.trim().split(" ");StringBuilder res = new StringBuilder();for (int i = split.length - 1; i >= 0; i--) {if (!split[i].equals("")) {res.append(split[i]).append(" ");}}return res.toString().trim();}
}
?Python版本:?
class Solution:def reverseWords(self, s: str) -> str:return ' '.join(s.strip().split()[::-1])
四、復雜度分析
4.1 方法一:雙指針
- 時間復雜度 O(N) : 其中 N 為字符串 s 的長度,線性遍歷字符串。
- 空間復雜度 O(N) : 新建的 list(Python) 或 StringBuilder(Java) 中的字符串總長度 ≤ N ,占用 O(N) 大小的額外空間。
4.2 方法二:分割 + 倒序
- 時間復雜度 O(N) : 總體為線性時間復雜度,各函數時間復雜度和參考資料鏈接如下。
- split() 方法: 為 O(N) 。
- trim() 和 strip() 方法: 最差情況下(當字符串全為空格時),為 O(N) 。
- join() 方法: 為 O(N) 。
- reverse() 方法: 為 O(N) 。
- 空間復雜度 O(N)?: 單詞列表 strs 占用線性大小的額外空間。