力扣第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) - 1while left < right:# 分别交换左右指针所指的值text[left], text[right] = text[right], text[left]left += 1right -= 1return text# 将输入的字符串s转化成列表resres = list(s)# 遍历列表resfor 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解答,仅仅是个人学习资料记录,也十分高兴我的见解可以帮助其他的正在做这个题目的同学,基础较差,仅仅是个人见解,大神勿喷,欢迎交流,谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/1430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

迎接大模型时代:程序员的挑战与应对

随着人工智能技术的迅猛发展&#xff0c;大模型已成为当前人工智能领域的重要趋势之一。大模型具有更强大的表征能力和泛化能力&#xff0c;已在自然语言处理、计算机视觉等领域取得了显著成果。然而&#xff0c;大模型的出现也给程序员带来了新的挑战和机遇。 大模型对程序员…

通过v-if渲染的element-ui表单,校验规则不生效的问题

因为form-item绑定验证事件是在mounted中进行的&#xff0c;规则变化后没有进行重新绑定验证事件&#xff0c;v-if渲染组件节点diff后被复用了&#xff0c;所以验证也就自然失效了 例如&#xff1a;通过动态选择类型来控制驾驶人是否显示&#xff0c;并且是必填项 给每一个el…

创建Vue项目后的初始化操作-解决Vue项目中盒子高度100%不生效问题

解决Vue项目中盒子高度100%不生效问题。 &#xff08;由于最近create的项目有点多&#xff0c;记录一下&#xff09;。 文章目录 方法一&#xff1a;对症下药方法二&#xff1a;偏方补充 方法一&#xff1a;对症下药 在项目根目录/public/index.html文件中的head里加入以下代码…

Java 与垃圾回收有关的方法

1. gc 调用垃圾回收器的方法是 gc&#xff0c;该方法在 System 类和 Runtime 类中都存在。 在 Runtime 类中&#xff0c;方法 gc 是实例方法&#xff0c;方法 System.gc 是调用该方法的一种传统而便捷的方法。在 System 类中&#xff0c;方法 gc 是静态方法&#xff0c;该方法…

oracle一次sql优化笔记

背景&#xff1a;两个百万级数据量表需要连接&#xff0c;加全索引的情况下速度仍不见改善&#xff0c;苦查一下午解决问题未遂。 解决&#xff1a;经大佬指点了解到oracle优化器提示&#xff0c;使用/* USE_HASH(table1 table2) */或者/* USE_MERGE(table1 table2) */来指导优…

P5732 【深基5.习7】杨辉三角

此题可以为杨辉三角&#xff0c;可以看一下这篇文章: 传送门 AC代码&#xff1a; #include<iostream>using namespace std;const int N 30; int arr[N][N];int main() {int n;cin >> n ;arr[1][1] 1;for(int i1;i<n;i){for(int j1;j<i;j){if(j 1 || j …

括号成对匹配

括号成对匹配 题目 括号成对匹配。例如&#xff1a;[a{b©d}e]匹配成功&#xff0c;a(b}匹配不成功 思路 这题的考察点是栈的原理&#xff0c;可以把括号匹配看成入栈和出栈&#xff0c;如果是左边的括号一律入栈&#xff1b;如果是右括号需要先与对应的左括号进行对比…

Callable and FutureTask

Callable 由关系图可知&#xff0c;Callable和Runnable一样&#xff0c;也是一个函数式接口&#xff0c;可以使用Lambda表达式 与之不同的是&#xff0c;其内部的call()方法可以抛出异常且能return一个返回值 Callable<Object> callable new Callable() {Overridepublic…

网上赚钱新姿势:日赚二三十,十大靠谱平台任你选!

互联网时代下&#xff0c;网络兼职已成为许多人追求额外收入的热门选择。互联网的广泛普及与发展&#xff0c;不仅让人们轻松获取海量信息&#xff0c;更为我们提供了多样化的兼职机会。这些兼职工作不仅时间自由&#xff0c;而且种类繁多&#xff0c;适合各种人群参与。接下来…

JavaWeb 监听器

Javaweb监听器是一种特殊的类&#xff0c;用于监听Web应用程序中的事件和对象。它可以监听Web应用程序的启动和关闭事件&#xff0c;会话的创建和销毁事件&#xff0c;以及请求和响应的事件等。监听器可以在特定事件发生时执行一些特定的操作&#xff0c;比如记录日志、初始化资…

【AR开发示例】实现AR管线巡检

写在前面的话 这是一篇旧文档&#xff0c;代码仓库见 https://gitee.com/tanyunxiu/AR-pipe 本文档是基于超图移动端SDK的AR模块开发的示例&#xff0c;仅供参考&#xff0c;SDK在持续迭代中&#xff0c;相关描述可能有变化。 示例介绍 这是一个使用AR查看墙内管线的基础示…

Ant Design中Tree使用defaultExpandAll属性后不会默认展开所有节点怎么办?

最近做前端项目时&#xff0c;使用到了 tree 组件&#xff0c;选择使用 Ant Design 中的 tree 组件&#xff0c;默认所有节点初始时全部展开&#xff0c;使用 defaultExpandAll 属性。但是显示的时候&#xff0c;一个节点都没展开。于是调研了一下这个问题。发现有以下问题&…

leetcode刷题(python)——(六)

01.03.07 练习题目&#xff08;第 06 天&#xff09; 1. 0506. 相对名次 1.1 题目大意 描述&#xff1a;给定一个长度为 n n n 的数组 s c o r e score score。其中 s c o r e [ i ] score[i] score[i] 表示第 i i i 名运动员在比赛中的成绩。所有成绩互不相同。 要求&…

在 Vue中,v-for 指令的使用

在 Vue中&#xff0c;v-for 指令用于渲染一个列表&#xff0c;基于源数据多次渲染元素或模板块。它对于展示数组或对象中的数据特别有用。 数组渲染 假设你有一个数组&#xff0c;并且你想为每个数组元素渲染一个 <li> 标签&#xff1a; <template> <ul>…

Spring Cloud 运维篇1——Jenkins CI/CD 持续集成部署

Jenkins 1、Jenkins是什么&#xff1f; Jenkins 是一款开源 CI/CD 软件&#xff0c;用于自动化各种任务&#xff0c;包括构建、测试和部署软件。 Jenkins 支持各种运行方式&#xff0c;可通过系统包、Docker 或者一个独立的 Java 程序。 Jenkins Docker Compose持续集成流…

k8s安装,linux-ubuntu上面kubernetes详细安装过程

官方文档&#xff1a;https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/ 环境配置 该部分每个主机都要执行 如果你确定不需要某个特定设置&#xff0c;则可以跳过它。 设置root登录 sudo passwd root sudo vim /etc/ssh/sshd_config Perm…

HarmonyOS NEXT 使用XComponent + Vsync 实现自定义动画

介绍 XComponent 提供了应用在 native 侧调用 OpenGLES 图形接口的能力&#xff0c;本文主要介绍如何配合 Vsync 事件&#xff0c;完成自定义动画。在这种实现方式下&#xff0c;自定义动画的绘制不在 UI 主线程中完成&#xff0c;即使主线程卡顿&#xff0c;动画效果也不会受…

晶圆制造之MPW(多项目晶圆)简介

01、MPW是什么&#xff1f; 在半导体行业中&#xff0c;MPW 是 "Multi Project Wafer" 的缩写&#xff0c;中文意思是多项目晶圆。MPW 的主要思想是将使用相同工艺的多个集成电路设计放在同一晶圆片上进行流片&#xff08;即制造&#xff09;。这种方法允许多个设计共…

java学习笔记6

11. 类的封装 ​ 在Java中,**封装(Encapsulation)**是面向对象编程中的重要概念,它指的是将类的数据(属性)和行为(方法)绑定在一起,并对外部隐藏数据的具体实现细节,只通过公共方法来访问和操作数据。这有助于提高代码的安全性、可维护性和灵活性。 11.1 为什要封装 …

Python exe 文件反编译为 Python 脚本

文章目录 前言版本反编译Python 可执行文件&#xff08;.exe&#xff09;反编译打包一个简单的 .exe 可执行文件提取 pyc 文件使用脚本提取使用工具提取 将 .pyc 文件转换为 Python 脚本入口运行类非入口运行类转换补全后的 pyc 文件uncompyle6 反编译在线工具 可能遇到的问题P…