344. 反转字符串
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left = 0
right = len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
双指针法,左右各一个指针并且进行字符交换,注意只有列表才可以两两交换,字符串只能够用切片反转 [::-1]。
541. 反转字符串 II
class Solution:
def reverseStr(self, s: str, k: int) -> str:
l = list(s)
for i in range(0, len(l), 2*k):
l[i:i+k] = l[i:i+k][::-1]
return ''.join(l)
按照题目的要求,每次遍历 2k 个字符,然后对前 k 个字符进行反转,字符串反转用 [::-1] 即可。
557. 反转字符串中的单词 III
class Solution:
def reverseWords(self, s: str) -> str:
return ' '.join(word[::-1] for word in s.split(' '))
用 split 分隔出每个单词,然后用 [::-1] 反转单词,最后再用 join 结合一起即可。
125. 验证回文串
class Solution:
def isPalindrome(self, s: str) -> bool:
left = 0
right = len(s) - 1
while left < right:
if not s[left].isalnum():
left += 1
continue
if not s[right].isalnum():
right -= 1
continue
if s[left].lower() != s[right].lower():
return False
else:
left += 1
right -= 1
return True
双指针法,注意指针如果指向的不是数字或者字母就移到下一位,直到都指向数字或字符为止。然后对两个指针指向的字符进行比较,直接转化为小写比较即可(对数字用小写也不会报错),不相等就返回 False,否则就下一位。
345. 反转字符串中的元音字母
class Solution:
def reverseVowels(self, s: str) -> str:
l = list(s)
left = 0
right = len(s) - 1
vowels = ('a', 'e', 'i', 'o', 'u')
while left < right:
while left < right and l[left].lower() not in vowels:
left += 1
while left < right and l[right].lower() not in vowels:
right -= 1
if left < right:
l[left], l[right] = l[right], l[left]
left += 1
right -= 1
return ''.join(l)
还是双指针法,同样的,如果指针指向的不是元音字母就移到下一位,直到是元音字母为止,然后对两个指针指向的字符进行交换即可。
3. 无重复字符的最长子串
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
left = 0
right = 0
window = dict()
ans = 0
while right < len(s):
if s[right] not in window:
window[s[right]] = 1
else:
window[s[right]] += 1
while window[s[right]] > 1:
window[s[left]] -= 1
left += 1
ans = max(ans, right - left + 1)
right += 1
return ans
双指针 + 滑动窗口,初始时先让 right 指针向右移位,遍历到的字符记录在滑动窗口中,直到有字符是第二次出现,此时就开始让 left 指针右移,直到滑动窗口中没有重复字符为止,对所有的无重复字符子串(滑动窗口)取长度最大值即可。
151. 颠倒字符串中的单词
class Solution:
def reverseWords(self, s: str) -> str:
return ' '.join(reversed(s.split()))
这题用内置函数就是一行,要注意的是 reversed() 比切片反转 [::-1] 要更快,因为前者只是生成了一个迭代器,而后者是创建了一个新的列表。如果是自己实现的话,代码如下:
class Solution:
def trim_spaces(self, s: str) -> list:
left, right = 0, len(s) - 1
# 去掉字符串开头的空白字符
while left <= right and s[left] == ' ':
left += 1
# 去掉字符串末尾的空白字符
while left <= right and s[right] == ' ':
right -= 1
# 将字符串间多余的空白字符去除
output = []
while left <= right: # 等于right的也要考虑,因为只用了left一个指针遍历
if s[left] != ' ': # 不是空白字符
output.append(s[left])
elif output[-1] != ' ': # 是第一个出现的空白字符
output.append(s[left])
left += 1
return output
def reverse(self, l: list, left: int, right: int) -> None:
while left < right:
l[left], l[right] = l[right], l[left]
left, right = left + 1, right - 1
def reverse_each_word(self, l: list) -> None:
n = len(l)
start = end = 0
while start < n:
# 循环至单词的末尾
while end < n and l[end] != ' ':
end += 1
# 翻转单词
self.reverse(l, start, end - 1)
# 更新start,去找下一个单词
start = end + 1
end += 1
def reverseWords(self, s: str) -> str:
l = self.trim_spaces(s)
# 翻转字符串
self.reverse(l, 0, len(l) - 1)
# 翻转每个单词
self.reverse_each_word(l)
return ''.join(l)
分三步走:移除多余空格、将整个字符串反转、将每个单词反转。要注意各个指针的范围。