Day08 代码随想录刷题
知识点:字符串,列表,指针
一、LeetCode344.反转字符数组
1.解题思路
不要分配额外空间,必须原地修改输入数组,使用O(1) 的额外空间解决问题。
2.代码实现
2.1 方法一:双指针
class Solution:
#双指针
def reverseString(self, s: List[str]) -> None:
left = 0
right = len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
2.2 方法二:栈
class Solution:
#栈
def reverseString(self, s: List[str]) -> None:
stack = []
for c in s:
stack.append(c)
for i in range(len(s)):
s[i] = stack.pop()
2.3 方法三:range,遍历一半
class Solution:
#range
def reverseString(self, s: List[str]) -> None:
n = len(s) - 1
for i in range(n//2):
s[i],s[n - i] = s[n - i], s[i]
2.4 方法四:库函数/切片/列表推导
新知识:
reversed()
:将列表、字符串切片进行反转,该函数返回的是一个反向迭代器,即会按照反转后的顺序依次返回,需要用一个相应范围的容器来装。其中,对于字符串我们还可以直接利用切片反转
class Solution:
#库函数
def reverseString01(self, s: List[str]) -> None:
s[:] = reversed(s)
#切片
def reverseString02(self, s: List[str]) -> None:
s[:] = s[::-1]
#列表推导
def reverseString03(self, s: List[str]) -> None:
s[:] = [s[i] for i in range(len(s) - 1, -1, -1)]
二、LeetCode541.反转字符II
1.解题思路
每2k个字符,反转其前k个字符。每次反转k个字符,反转结束后反转起点走2k步。字符串不可修改,所以可转换成list进行操作。
额外新知识:
''.join(res):
将res列表内的各个元素通过’'内的元素相连成字符串
2.代码实现
2.1 方法一:库函数
class Solution:
#库函数
def reverseStr(self, s: str, k: int) -> str:
res = list(s)
for cur in range(0, len(s)-1, 2*k):
res[cur:cur + k] = reversed(res[cur:cur + k])
return ''.join(res)
2.2 方法二:字符串组装
class Solution:
#字符串组装:reversed
def reverseStr01(self, s: str, k: int) -> str:
for cur in range(0, len(s)-1, 2*k):
s = s[:cur] + ''.join(reversed(s[cur:cur + k])) + s[cur + k:]
return s
#字符串组装:切片
def reverseStr02(self, s: str, k: int) -> str:
cur = 0
while cur < len(s) - 1:
s = s[:cur] + s[cur:cur + k][::-1] + s[cur + k:]
cur = cur + 2*k
return s
三、剑指Offer 05.替换空格
1.解题思路
把字符串中的每个空格用%20
替代。空格本身占1位,要求的替代字符串共占3位,所以字符串中有几个空格字符我们就应该多开辟两倍的空间。可用指针来解决问题。
2.代码实现
2.1 方法一:指针手撕代码
class Solution:
#手撕代码
def replaceSpace(self, s: str) -> str:
#计算空格数
n = s.count(' ')
#str转list便于操作
res = list(s)
#扩展空间,也用空格代替
res.extend([' ']*n*2)
#创建指针,对应拓展空间前后的最后一位
left, right = len(s) - 1, len(res) - 1
while left >= 0:
if res[left] != ' ':
#left所指不是空格,则所指的值放到后面去
res[right] = res[left]
right -= 1
else:
#left所指的是空格,则right对应及前2位开始存放"%20"
res[right - 2:right + 1] = '%20'
right -= 3
left -= 1
#列表组装为字符串并返回
return ''.join(res)
2.2 方法二:库函数replace
class Solution:
#库函数replace一步到位
def replaceSpace(self, s: str) -> str:
s = s.replace(' ',"%20")
return s
四、LeetCode151.反转字符串中的单词
1.解题思路
针对这一问题有一个通解,就是先各单元反转,再全部反转。
还有一种方法就是方法一这种,根据情况,交换位置即可。
2.代码实现
2.1 方法一:反转单词
class Solution:
#反转单词
def reverseWords(self, s: str) -> str:
# 将字符串去两头空格后,按照单词拆成列表
s = s.strip()
word_list = s.split()
# 列表各单词整体交换顺序
left, right = 0, len(word_list) - 1
while left < right:
word_list[left], word_list[right] = word_list[right], word_list[left]
left += 1
right -= 1
# 将列表转换成字符串
return " ".join(word_list)
2.2 方法二:通解:反转先整体再局部
class Solution:
#通解
def reverseWords(self, s: str) -> str:
s = s.strip()
#整体反转
s = s[::-1]
#每个单词再各自反转
s = ' '.join(word[::-1] for word in s.split())
return s
五、剑指Offer 58.II.左旋转字符串
1.解题思路
本题类似上一题,要么通解手撕,要么找到规律直接交换。
2.代码实现
2.1 方法一:直接交换:切片
class Solution:
#切片:只有两部分,直接切片交换
def reverseLeftWords(self, s: str, n: int) -> str:
return s[n:] + s[:n]
2.2 方法二:模
class Solution:
#模+下标:利用索引的规律取模索引
def reverseLeftWords(self, s: str, n: int) -> str:
res = ''
for i in range(len(s)):
j = (i + n)%len(s)
res = res + s[j]
return res
#模+切片:复制一段,选取对应位置
def reverseLeftWords(self, s: str, n: int) -> str:
s = s + s
return s[n:n+len(s)//2]
2.3 方法三:通解:反转先局部再整体
class Solution:
#reversed()库函数法
def reverseWords(self, s: str) -> str:
s = list(s)
s[0:n] = reversed(s[0:n])
s[n:] = reversed(s[n:])
#s.reverse()函数也可
s = reversed(s)
return ''.join(s)
#自己写的通解:先局部反转,再整体反转————切片法
def reverseLeftWords(self, s: str, n: int) -> str:
s = s[n - 1:: -1] + s[len(s) - 1:n - 1:-1]
s = s[::-1]
return s