541 反转字符串Ⅱ
给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
示例:
输入: s = “abcdefg”, k = 2
输出: “bacdfeg”
我的思路
因为对于一个字符串,都每次是2k个字符,所有我可以先找出一个字符串中有多少个2k字符,对于这2k个字符,处理逻辑是一样的(即反转这 2k 个字符中的前 k 个字符),所以我可以使用一个循环来实现。然后对于剩下的字符,先要判断它是少于k还是位于k与2k之间,然后再去实现对应的操作。
class Solution(object):
def reverseStr(self, s, k):
"""
:type s: str
:type k: int
:rtype: str
"""
cnt, remain = divmod(len(s), 2*k) # 一共有多少个2k 以及求完2k之后剩余的
result = ''
for i in range(cnt): # 对于每2k个字符
tmp = s[i*2*k:(i+1)*2*k-k] # 每2k个字符的前k个
tmp = tmp[::-1] # 进行反转
result += tmp # 加上反转之后的
result += s[(i+1)*2*k-k:(i+1)*2*k] # 加上2k中剩余的k个字符 保持不变
if len(s)-len(result) < k: # 处理完cnt*2k个字符之后 小于k
tmp = s[cnt*2*k:]
tmp = tmp[::-1]
result += tmp
elif k <= len(s)-len(result) < 2*k: # 小于2k 大于等于k
tmp = s[cnt*2*k:cnt*2*k+k]
tmp = tmp[::-1]
result += tmp
# result还得加上剩余的
result += s[cnt*2*k+k:]
return result
另外一种解法(简便)
class Solution:
def reverseStr(self, s: str, k: int) -> str:
"""
1. 使用range(start, end, step)来确定需要调换的初始位置
2. 对于字符串s = 'abc',如果使用s[0:999] ===> 'abc'。字符串末尾如果超过最大长度,则会返回至字符串最后一个值,这个特性可以避免一些边界条件的处理。
3. 用切片整体替换,而不是一个个替换.
"""
def reverse_substring(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 cur in range(0, len(s), 2 * k): # 这个处理同时蕴含了三种逻辑
res[cur: cur + k] = reverse_substring(res[cur: cur + k])
return ''.join(res) # 注意res本来是list形式 所以需要 ''.join构成字符串