今天题目写的还比较顺利,有一两道暂时想不出思路的稍微看下解析也马上能自己写出来了。除了一些算法思想,今天也学到了list转str的技巧,例如'a'.join(s)
,这条语句的意思就是将列表s转化为字符串,列表中的元素用a隔开,a如果为空,就代表直接相连。
344.反转字符串 - 🔗
讲解 - 🔗
💡这道题思路还是挺清晰的,可以用双指针从两遍往中间走,直到left>right结束。
方法一:双指针
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
left, right = 0, len(s) - 1
while left <= right:
tmp = s[left]
s[left] = s[right]
s[right] = tmp
# s[left], s[right] = s[right], s[left] # 建议写法
left += 1
right -= 1
上面这段是我自己写的代码,但是看完参考代码之后,我发现python中交换元素可以直接写成a, b = b, a
,而无需向我上面那样多设置一个tmp。
方法二:使用range
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
n = len(s)
for i in range(n // 2):
s[i], s[n - i - 1] = s[n - i - 1], s[i]
方法三:使用切片
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = s[::-1]
⚠️python中内置的reversed()
函数可以直接实现反转,例如s[:] = reversed(s)
541. 反转字符串II - 🔗
讲解 - 🔗
💡这道题感觉思路比较混乱,写着写着就被k和2k绕进去了。看了文字解析稍微有点头绪。
方法一:双指针
class Solution:
def reverseString(self, s: List[str], left: int, right: int) -> None:
while left <= right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
def reverseStr(self, s: str, k: int) -> str:
list_s = list(s)
i = 0
# i每次前进2k
while i <= len(list_s):
#在2k中反转k内的字符
left, right = i, i + k - 1
# 如果right超出了字符串的长度,也就是剩余字符少于k个,则全部反转
if right >= len(list_s):
self.reverseString(list_s, left, len(s) - 1)
else:
self.reverseString(list_s, left, right)
i += 2 * k
return ''.join(list_s)
方法二:使用切片
# Two pointers. Another is inside the loop.
p = 0
while p < len(s):
p2 = p + k
# Written in this could be more pythonic.
s = s[:p] + s[p: p2][::-1] + s[p2:]
p = p + 2 * k
return s
在这段代码中,学到了对字符串切片的另一种表达s[a:b][::-1]
-> a和b应该是有效的索引值,表示所需子字符串的起始和结束位置。[::-1]表示对切片后的结果进行反向操作,即将字符串元素按相反的顺序重新组合成一个新的字符串。
卡码网:54.替换数字 - 🔗
讲解 - 🔗
💡这道题如果可以使用额外空间感觉还是挺简单的,直接将所有元素放到list中,将数字替换为number即可。
class Solution:
def transferToNumber(self, s: str) -> str:
list_s = list(s)
for i in range(len(list_s)):
if list_s[i] >= 'a' and list_s[i] <='z':
continue
else:
list_s[i] = 'number'
return ''.join(list_s)
r = Solution()
s = input()
print(r.transferToNumber(s))
151.翻转字符串里的单词 - 🔗
讲解 - 🔗
💡这道题跟上道题一样,创建额外空间的做法比较好想。直接把所有单词,倒序插入一个新的list即可。
方法一:
class Solution:
def reverseWords(self, s: str) -> str:
list_s = []
tmp = ""
for i in s:
if i != ' ':
tmp += i
else:
if tmp:
# 往前插入
list_s.insert(0,tmp)
tmp = ""
if tmp:
list_s.insert(0,tmp)
return ' '.join(list_s)
方法二:使用双指针
class Solution:
def reverseWords(self, s: str) -> str:
# 将字符串拆分为单词,即转换成列表类型
words = s.split()
# 反转单词
left, right = 0, len(words) - 1
while left < right:
words[left], words[right] = words[right], words[left]
left += 1
right -= 1
# 将列表转换成字符串
return " ".join(words)
卡码网:55.右旋转字符串 - 🔗
讲解 - 🔗
💡这道题最直接的想法就是开辟额外空间,但是就变得很简单了。看了下讲解,有一个思路我觉得很巧妙,就是整体反转+局部反转,可以先将整个字符串反转,例如abcdefg
变成gfedcba
,然后再根据k = 2
,将字符串分为两部分,gf
和edcba
,再分别对这两部分进行反转,就可以得到最后的结果。
方法一:开辟新空间
# 开辟额外空间
class Solution:
def rightReverse(self, k: int, s: str) -> str:
return s[len(s) - k:] + s[:len(s) - k]
k = int(input())
s = input()
r = Solution()
print(r.rightReverse(k, s))
方法二:整体反转+局部反转
# 整体反转 + 局部反转
class Solution:
def reverseStr(self, s: str, left: int, right: int) -> str:
list_s = list(s)
while left <= right:
list_s[left], list_s[right] = list_s[right], list_s[left]
left += 1
right -= 1
return ''.join(list_s)
def rightReverse(self, k: int, s: str) -> str:
# 整体反转
s = self.reverseStr(s, 0, len(s) - 1)
s = self.reverseStr(s, 0, k - 1)
s = self.reverseStr(s, k, len(s) - 1)
return s
k = int(input())
s = input()
r = Solution()
print(r.rightReverse(k, s))