344.反转字符串
什么时候用库函数:
如果题目关键的部分直接用库函数就可以解决,建议不要使用库函数。
如果库函数仅仅是 解题过程中的一小部分,并且你已经很清楚这个库函数的内部实现原理的话,可以考虑使用库函数。
解题思路
左右双指针,一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
l = 0
r = len(s) - 1
while l < r:
s[l], s[r] = s[r], s[l]
l += 1
r -= 1
时间复杂度 O(N)
空间复杂度 O(1)
541. 反转字符串II
解题思路
1. 左右双指针,反转字符串
2. res = list(a), 遍历res, 让i 每次走 2k步,通过切片更新res[i:i + k] 。
for loop里其实需要讨论两种情况:
if i + k <= len(s):
res[i:i+k] = reverse_s(res[i:i+k])
else:
res[i:len(s)] = reverse_s( res[i:len(s)])
但res[i: i + k] ,i始终不会越界,i+k即使大于了数组长度,切片时,也会在len(s) -1的index终止。
遇到的问题
要将string先转化为list
为了处理逻辑:每隔2k个字符的前k的字符,写了一堆逻辑代码。其实在遍历字符串的过程中,只要让 i += (2 * k),i 每次移动 2 * k 就可以了,然后判断是否需要有反转的区间。
class Solution:
def reverseStr(self, s: str, k: int) -> str:
def reverse_s(text):
left, right = 0, len(text) - 1
while left < right:
text[left], text[right] = text[right], text[left]
left += 1
right -= 1
return text
res = list(s)
for i in range(0, len(s), 2 * k):
res[i:i+k] = reverse_s(res[i:i+k])
return "".join(res)
时间复杂度 O(N)
空间复杂度 O(N)
剑指Offer 05.替换空格
很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作.
这么做有两个好处:
- 不用申请新数组。
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
算法:
统计字符串里有几个空格
res =字符串转化的list
给res扩容
左右指针,左指针指向原字符串的末位index,右指针指向res的末位。都向左移动,遍历res数组:
如果原字符串的index值不是空格,交换res[right] res[left] 值,right 和left各左移一位
否则,将切片值替换,res[right - 2: right + 1] = '%20', right左移三位,left左移一位
最后将res数组转化为字符串返回
class Solution:
def replaceSpace(self, s: str) -> str:
counter = s.count(' ')
res = list(s)
# 每碰到一个空格就多拓展两个格子,1 + 2 = 3个位置存’%20‘
res.extend([' '] * counter * 2)
# 原始字符串的末尾,拓展后的末尾
left, right = len(s) - 1, len(res) - 1
while left >= 0:
if res[left] != ' ':
res[right] = res[left]
right -= 1
else:
# [right - 2, right), 左闭右开
res[right - 2: right + 1] = '%20'
right -= 3
left -= 1
return ''.join(res)
时间复杂度 O(N)
空间复杂度 O(N)
151.翻转字符串里的单词
Reverse Words in a String - LeetCode
解题思路
先整体反转再局部反转
- 移除多余空格
- 将整个字符串反转
- 将每个单词反转
class Solution: 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) def trim_spaces(self, s): a = list(s) slow = fast = 0 while fast < len(a): if a[fast] != " ": if slow != 0: a[slow] = " " slow += 1 while fast < len(a) and a[fast] != " ": a[slow] = a[fast] slow += 1 fast += 1 else: fast += 1 return a[:slow] def reverse(self, l, left, right): while left < right: l[left], l[right] = l[right], l[left] left += 1 right -= 1 def reverse_each_word(self, l): start = 0 for end in range(len(l) + 1): if end == len(l) or l[end] == " ": self.reverse(l, start, end - 1) start = end + 1
时间复杂度 O(N)
空间复杂度 O(N)
剑指Offer58-II.左旋转字符串
通过局部反转+整体反转 达到左旋转的目的。
具体步骤为:
- 反转区间为前n的子串
- 反转区间为n到末尾的子串
- 反转整个字符串
class Solution: def reverseLeftWords(self, s: str, n: int) -> str: def reverse_sub(lst, left, right): while left < right: lst[left], lst[right] = lst[right], lst[left] left += 1 right -= 1 res = list(s) end = len(res) - 1 reverse_sub(res, 0, n - 1) reverse_sub(res, n, end) reverse_sub(res, 0, end) return ''.join(res)