344. 反转字符串
题目要求:不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
重点:
- 如何做到反转的效果?其实就是不断地首尾交换,利用双指针法,一个左指针从头开始,一个右指针从尾开始,两个指针同时向中间移动,不断地交换左右指针对应的元素即可
class Solution(object):
def reverseString(self, s):
"""
:type s: List[str]
:rtype: None Do not return anything, modify s in-place instead.
"""
left = 0
right = len(s)-1
while left < right: # 当left=right的时候,指向同一个元素,就不用交换了(奇数个字符的场景)
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
541. 反转字符串 II
https://leetcode.cn/problems/reverse-string-ii/
重点:
- 注意这道题每次是反转2k个字符中的前k个字符,然后处理下一段2k个字符,当需要固定规律一段一段去处理字符串的时候,要想想在for循环的表达式上做文章。
- 编写reverse函数,只反转字符串从i到i+k-1的部分
class Solution(object):
def reverseStr(self, s, k):
"""
:type s: str
:type k: int
:rtype: str
"""
def reverse(s, left, right): # 只反转s从left到right的部分
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
return s
remain = len(s)
s = list(s)
i = 0
while i < len(s):
if remain < k:
s = reverse(s, i, len(s)-1) # 将剩余字符全部反转
else:
s = reverse(s, i, i+k-1) # 反转前k个字符
i += 2*k
remain -= 2*k
return ''.join(s)
剑指 Offer 05. 替换空格
注意,如果将s变成一个列表,然后去遍历里面的元素,如果遇到空格,则将元素改为’%20’,这样写的话,不能写for i in s,因为这样写i就是一个字符串,在python中,字符串是不可变类型,所以当i=空格时,如果令i=‘%20’,相当于是新建了一个i,令i=‘20%’,而不是对列表中的迭代项i进行修改,所以会发现程序运行后空格依然存在,并没有被修改。
class Solution(object):
def replaceSpace(self, s):
"""
:type s: str
:rtype: str
"""
s = s.split(' ')
return '%20'.join(s)
151. 反转字符串中的单词
- 用python的split函数,只会去掉单词间的一个空格,不会去掉多余的空格以及前导空格和尾随空格
- 先去除前导空格,尾随空格,以及单词之间多余的空格
- 反转整个字符串
- 逐个将单词反转
- 整体反转+局部反转,即可达到反转单词的目的。先整体反转,让单词的顺序反转(不管单词的内部),再局部反转,使得单词内部的字母顺序正确。
class Solution(object):
def reverseWords(self, s):
"""
:type s: str
:rtype: str
"""
def reverse(s, left, right): # 左闭右开
right -= 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
return s
s = list(s)
res = []
# 去除前导空格
i = 0
while s[i] == ' ':
i += 1
# 去除尾随空格
j = len(s)-1
while s[j] == ' ':
j -= 1
while i <= j: # 去除单词之间的空格
if s[i] == ' ':
while s[i] == ' ':
i += 1
res.append(' ')
else:
res.append(s[i])
i += 1
res = res[::-1] # 将整个字符串反转
start = 0 # 单词的起始位置
end = 0 # 单词的结束位置(不包含end)
while end < len(res):
# 遇到空格,说明一个单词结束了,则从索引start到end-1是一个单词
if res[end] == ' ': # 注意end是索引,要加上res啊
res = reverse(res, start, end) # 反转单词
start = end+1 # 将start更改到下一个单词的起始位置
end += 1
res = reverse(res, start, end) # 反转最后一个单词
return ''.join(res)
剑指 Offer 58 - II. 左旋转字符串
- python切片操作:s[start_index:end_index:step]
包含start_index,不包含end_index(不用管左闭右开还是什么,就是不包含end_index(两个冒号之间)这个位置的索引)
step是步长,如果为正则代表方向从左往右(索引从小到大)
如果为负则代表方向从右往左(索引从大到小)
注意步长的方向要和start_index:end_index的方向一致 - 这道题的关键点是整体反转+局部反转先反转整个字符串,然后反转末尾的n个字符,最后反转剩余的字符。
class Solution(object):
def reverseLeftWords(self, s, n):
"""
:type s: str
:type n: int
:rtype: str
"""
s = list(s)
l = len(s)
s = s[::-1]
s[:l-n] = s[l-n-1::-1]
s[l-n::] = s[l-1:l-n-1:-1]
return ''.join(s)