Leetcode Link: 151. 颠倒字符串中的单词 - 力扣(LeetCode)
题目
给你一个字符串 s ,颠倒字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

前导空格
"abc"中没有前导和尾随空格" abc"有前导空格"abc "有尾随空格
解法一
思路: 自带函数直接模拟,秒啊!
题解:
class Solution:
def reverseWords(self, s: str) -> str:
sp = s.split(' ')
new = [val for val in sp if val != '']
return ' '.join(new[::-1])本题注意如下的情况:
>>> s = "~hello~world~" # ~表空格
>>> s.spilt(' ')
["", "hello", "world", ""] # ""是空字符串
>>> s = "~hello~~world~" # ~表空格
>>> s.spilt(' ')
["", "hello", "", "world", ""] # ""是空字符串解法二
思路:双指针
前面的指针 (former) 和后面的指针 (latter) 组成一个窗口,有如下几个需要注意的细节
- 窗口左开右闭
[l, r) - 窗口扩张要遇到空格时,判断当前窗口是否存在内容且不为空格后,添加到新的数组中
- 最后不要忘记添加最后一个窗口,需要判断窗口内容
题解:
class Solution:
def reverseWords(self, s: str) -> str:
# [l, r)
l = r = 0
new = []
while(r<len(s)):
if s[r] != " ": # 右侧不是空格,入窗
r += 1
else: # 是空格,判断内容是否为空格(是空格时用 or 后面的判断)
if r == l or (r-l==1 and s[l]==" "):
r += 1
l = r
else:
new.append(s[l:r])
r += 1
l = r
if s[l:r]!="":
new.append(s[l:r])
return " ".join(new[::-1])Note
可以先去掉所有的前导空格和尾随空格
2 刷的时候一个更新版,先去掉了所有前导和尾随空格,似乎更好理解了
class Solution:
def reverseWords(self, s: str) -> str:
# 去掉前导和尾随空格
while(s[0] == ' '):
s = s[1:] # s[0] = '' 报错,str类型不能修改。
while(s[-1] == ' '):
s = s[:-1]
res = []
# [l, r), 窗口左闭右开
l, r = 0, 0
while(r<len(s)):
if s[r] != ' ': # 右侧没有遇到空格,入窗
r += 1
else: # 右侧遇到空格,添加单词,找到下一个不是空格的左起点。
res.append(s[l:r])
l = r
while(s[l] == ' '):
l += 1
r = l
res.append(s[l:r])
return ' '.join(res[::-1])
启发和联系
代码随想录中本问题的解不好。