力扣第541题: 反转字符串 II

题目:

给定一个字符串 s 和一个整数 k,从字符串开头算起, 每计数至 2k 个字符,就反转这 2k 个字符中的前 k 个字符。

如果剩余字符少于 k 个,则将剩余字符全部反转。

如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例:

输入: s = "abcdefg", k = 2
输出: "bacdfeg"

题目意图解析:

题目要求按照给定的步骤修改输入的字符串 s,具体步骤和规则如下:

  1. 字符串分块处理: 将字符串 s 按照长度 2k 进行分块。每块长度最多为 2k,按这种方式划分,字符串会被分成若干块。

  2. 每块内的操作: 对于每一块:

    • 如果块的长度等于 2k,则反转这个块中的前 k 个字符。
    • 如果块的长度少于 2k 但大于或等于 k,则仅反转这个块中的前 k 个字符,剩下的字符保持不变。
    • 如果块的长度少于 k,则将这个块中的所有字符全部反转。
  3. 结果连接: 处理完所有块之后,将每块处理后的结果连接起来,形成最终的字符串。

以题目中的示例来说明:

  • 输入字符串 s = "abcdefg"k = 2
  • 将字符串分为 2k = 4 个字符一组,得到 "abcd" 和 "efg" 两组。
  • 对 "abcd" 中的前 k = 2 个字符进行反转,得到 "bacd"。
  • 对 "efg",因为长度小于 2k 但大于 k,也反转前 k = 2 个字符,得到 "fecg"。
  • 连接处理后的两块结果 "bacd" 和 "fecg",得到最终输出 "bacdfeg"。

class Solution:
    def reverseStr(self, s: str, k: int) -> str:

        # 定义一个反转字符串函数
        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

        # 将输入的字符串s转化成列表res
        res = list(s)

        # 遍历列表res
        for cur in range(0, len(s), 2 * k):
            res[cur: cur + k] = reverse_substring(res[cur : cur + k])
        return ''.join(res)

上述代码实现解答:

1. 定义 reverse_substring 辅助函数

这个函数用于反转给定的字符串片段。具体步骤如下:

  • 接收一个字符串片段 text 作为参数。
  • 初始化两个指针 leftright,分别指向字符串的开始和结束位置。
  • 使用 while 循环,当 left 小于 right 时执行循环体:
    • 交换 leftright 指针所指向的字符。
    • left 指针向右移动一位。
    • right 指针向左移动一位。
  • left 不再小于 right 时,循环结束,此时字符串片段已被反转。
  • 返回修改后的字符串片段。

这个函数是处理字符串反转的核心逻辑,它直接在传入的列表片段上进行修改,由于列表是可变数据类型,这种修改是原地进行的。

2. reverseStr 方法

这个方法用来控制整个字符串的反转流程:

  • 将输入的字符串 s 转换成列表 res。这是因为字符串在 Python 中是不可变的,而列表允许我们进行原地修改。
  • 使用 for 循环遍历 res,步长为 2k,这意味着每次迭代跳过 2k 个字符。cur 是当前迭代的起始索引。
    • 在每次循环中,res[cur: cur + k] 选取从 cur 开始的 k 个字符。
    • 这个子列表通过 reverse_substring 函数进行反转。
    • 反转结果赋值回 res 的相应位置,由于是列表,所以这个操作修改了 res 的实际内容。
  • 完成所有迭代后,所有需要反转的部分已经在 res 中被正确反转。
  • 使用 join 函数将列表 res 转换回字符串,并返回这个字符串。

实际应用

假设 s = "abcdefg"k = 2。流程如下:

  • s 转为列表:res = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
  • 循环迭代:每次处理 2k = 4 个字符。
    • 第一次迭代:cur = 0,处理 res[0:2] -> ['a', 'b'] 反转为 ['b', 'a']
    • 第二次迭代:cur = 4,处理 res[4:6] -> ['e', 'f'] 反转为 ['f', 'e']
  • 最终列表:res = ['b', 'a', 'c', 'd', 'f', 'e', 'g']
  • 转换回字符串并返回:"bacdfeg"

上述过程逐步应用了字符串分块和反转的逻辑,实现了每隔 2k 字符的交替反转效果。

重难点代码解析:

for cur in range(0, len(s), 2 * k): 

这行代码中的 for 循环是用来迭代整个字符串 s,采用了特定的步长来确保每次迭代可以正确地按照指定的模式处理字符串。

range 函数的三个参数:

  • 第一个参数 0:这是 range 函数的起始值,表示循环将从索引 0 开始,也就是字符串的第一个字符。
  • 第二个参数 len(s):这是 range 函数的结束值,len(s) 表示字符串 s 的长度,这样确保循环覆盖整个字符串,但不包括 len(s) 本身,因为 range 是半开区间 [start, end)。
  • 第三个参数 2 * k:这是 range 函数的步长,决定了每次循环增加的索引数量。这里的 2 * k 表示每次迭代跳过 2k 个字符。这个设置是因为题目中的操作模式是:对每 2k 字符的前 k 字符进行反转,而后 k 字符保持原样。因此,每次处理后跳过 2k 个字符到下一个待处理区间的开始。

循环的操作逻辑:

循环结构使得每次循环都从序列的 cur 位置开始,处理长度为 k 的子序列进行反转(如果 cur + k 超过字符串长度,那么只处理从 cur 开始到字符串结束的部分)。

例子演示:

假设 s = "abcdefghijk"k = 3

  • 第一次循环:cur = 0,处理区间是 [0:3](即 "abc")。
  • 第二次循环:cur = 6,处理区间是 [6:9](即 "ghi")。

在每个循环迭代中,cur 指向的是每个 2k 区间的开始位置,这样设计循环是为了实现题目要求的每 2k 个字符中的前 k 个字符反转的功能。

res[cur: cur + k] = reverse_substring(res[cur: cur + k])

这句代码是实现字符串反转的核心部分,在整体 for 循环中的每次迭代里执行,具体地处理字符串中的特定子序列,可以分解这行代码为几个关键操作:

1. res[cur: cur + k]

这部分是一个列表切片操作,用于从列表 res 中选取从索引 cur 开始到 cur + k 的元素。这个切片包括从 curcur + k - 1 的所有元素,总共 k 个字符(如果存在的话;如果 cur + k 超出了列表的长度,它会简单地取到列表末尾)。这是要被反转的子字符串。

2. reverse_substring(res[cur: cur + k])

这个调用将上面提到的切片作为参数传递给 reverse_substring 函数。如前所述,reverse_substring 函数是一个翻转其输入的函数,并返回翻转后的列表(或子列表)。

3. res[cur: cur + k] = ...

这部分是赋值操作。函数 reverse_substring 返回的翻转后的列表将替换原来 res 列表中 curcur + k 的部分。这是一个原地修改,意味着 res 列表在这一操作后更新了其中的一段。

功能和作用

整个操作的作用是在列表 res 中的指定位置原地翻转 k 长度的子列表。这实现了题目要求的在每隔 2k 字符的区间内反转前 k 个字符的功能。这种方法利用了 Python 列表的可变性,通过原地修改来避免额外的内存分配,提高效率。

示例解析

假设 s = "abcdefghi"k = 3,经过 res = list(s) 后,res 将是 ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']

  • 在循环的第一次迭代(cur = 0),res[0:3]['a', 'b', 'c']。经过 reverse_substring 处理后,这部分变为 ['c', 'b', 'a'],并被重新赋值给 res[0:3],使得 res 变为 ['c', 'b', 'a', 'd', 'e', 'f', 'g', 'h', 'i']
  • 接下来的迭代会处理更远的区间,如 cur = 6,针对 ['g', 'h', 'i'] 等部分。

通过这样的操作,代码有效地在给定间隔内反转字符串的指定部分,同时保持其他部分不变。

  综上,本文的对于力扣541. 反转字符串 II的Python3解答,仅仅是个人学习资料记录,也十分高兴我的见解可以帮助其他的正在做这个题目的同学,基础较差,仅仅是个人见解,大神勿喷,欢迎交流,谢谢!

  • 28
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又在熬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值