力扣刷题-字符串-反转字符串Ⅱ

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构成字符串

你可能感兴趣的:(leetcode刷题,leetcode,算法,python,数据结构)