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
return
541. 反转字符串II
- 需要把字符串转换为list,才可以使用index查询。最后输出的时候使用"".join(s)转换为str。
- s[curr:curr+k]可以直接表示,不用边界控制,因为:
- 对于字符串s = ‘abc’,如果使用s[0:999] ===> ‘abc’。字符串末尾如果超过最大长度,则会返回至字符串最后一个值,这个特性可以避免一些边界条件的处理。
- for cur in range(0, len(s), 2 * k):以2k为step
- 第二种写法:s = s[:p] + s[p: p2][::-1] + s[p2:],直接用s[p:p2][::-1]进行反转
class Solution:
def reverseStr(self, s: str, k: int) -> str:
curr = 0
n = len(s)
while(curr < n):
if n - curr < k:
s = self.reverse(s, curr, n-1)
elif n-curr > 2*k:
s = self.reverse(s, curr, curr+k-1)
else:
s = self.reverse(s, curr, curr+k-1)
curr += 2*k
return s
def reverse(self, s, left, right):
s = list(s)
while(left < right):
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
return "".join(s)
卡码网:替换数字
- str1 = input()表示输入,很少在python里写输入输出来着
- 可以直接用符号比较字符的大小,也可以用ASCII码ord(“a”)
- 本地置换的话,就得先遍历一遍数一下有多少数字,每个数字需要扩张5个位置,s.resize()
- 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。(因为从前往后的话,容易覆盖还没有遍历的字符。
str1 = input()
def replace(s):
s = list(s)
output = ""
for i in range(len(s)):
if s[i] >= 'a' and s[i] <= 'z':
output += s[i]
else:
output += 'number'
return output
ans = replace(str1)
print(ans)
151. 翻转字符串里的单词
- 不知道为什么,这题写过了,但写的很不顺
- 第一个疑惑,python能在本地进行翻转吗,感觉很难写。
- 首先第一步去除多余的空格,是可以在本地用双指针法完成的吧。array[0],array[0:1]下标和切片。O(n)
- 第二步,翻转整个字符串,array[:len][::-1]。
- 第三步,对词进行翻转。记录下遇到的第一个非空格位置left,和最后一个非空格位置right。
---- 第一个思路是s = s[0:left]+s[left:right][::-1]+s[right:]是新的空间还是在原有空间上进行的?
---- 第二个思路是,tmp记录下right,while(left < right)进行交换,交换完left=right = tmp - 这样的话,不用额外空间,时间复杂度O(n)
- 如果python语言中字符串就是不可变的话,那么空间复杂度就是O(n),也就没必要这么做了
- 如果不在本地进行翻转,也就是另开一个res记录输出,就容易很多。从后往前的指针,输入res的时候直接用切片,这样word是正向的,res的单词是反向的:空间复杂度O(n),时间复杂度O(n),遍历一遍
class Solution:
def reverseWords(self, s: str) -> str:
# 从后往前的双指针
n = len(s)
i = n-1
j = n-1
res = []
while i >= 0:
while i >=0 and s[i] == ' ': # 跳过开头的空格
i -= 1
j = i
while i >=0 and s[i] != ' ':
i -= 1 # 找空格
res.append(s[i+1:j+1])
while i >=0 and s[i] == ' ': # 跳过结尾的空格
i -= 1
j = i
print(res)
return " ".join(res)
调库做法:
- 删除前后空白,s = s.strip()
- 反转字符串
- s.split()拆分单词,同时每个单词进行翻转
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
- 也可以先split后,用双指针翻转单词,这样比较清晰
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)
卡码网:右旋转字符串
卡码网用的是ACM模式,没怎么写过,很生疏,不会写输入输出,不过微信公众号上有一个模板
import sys
while True:
s = input().split() # 一行一行读取
a, b = int(s[0]), int(s[1])
if not a and not b: # 遇到 0, 0 则中断
break
print(a + b)
其实一直不太知道python做反转字符串的知识点是啥。。
import sys
k = int(input())
s = input()
# 1.在本地进行修改。也许吧
# 整体翻转,再局部翻转
s = "".join(reversed(s))
s = s[:k][::-1] + s[k:][::-1]
print(s)
# 2.不在本地进行修改
output = ""
n = len(s)
output = s[n-k:n] + s[:n-k]
print(output)
总结
- 字符串反转的一些函数:
- s = “”.join(reversed(s))
- s[::-1]
- 如果要具体写翻转的话,用双指针,一个前一个后,这样可以实现本地翻转
- words = s.split()得到的是一个word的list
- s = s.strip(),返回的应该还是字符串