力扣第92题——反转链表 II(C语言题解)

题目描述

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

方法一:穿针引线

我们以下图中黄色区域的链表反转为例。

使用「206. 反转链表」的解法,反转 left 到 right 部分以后,再拼接起来。我们还需要记录 left 的前一个节点,和 right 的后一个节点。如图所示:

算法步骤:

第 1 步:先将待反转的区域反转;
第 2 步:把 pre 的 next 指针指向反转以后的链表头节点,把反转以后的链表的尾节点的 next 指针指向 succ。

说明:编码细节我们不在题解中介绍了,请见下方代码。思路想明白以后,编码不是一件很难的事情。这里要提醒大家的是,链接什么时候切断,什么时候补上去,先后顺序一定要想清楚,如果想不清楚可以在纸上模拟.

void reverseLinkedList(struct ListNode *head) {// 也可以使用递归反转一个链表struct ListNode *pre = NULL;struct ListNode *cur = head;while (cur != NULL) {struct ListNode *next = cur->next;cur->next = pre;pre = cur;cur = next;}
}struct ListNode *reverseBetween(struct ListNode *head, int left, int right) {// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论struct ListNode *dummyNode = malloc(sizeof(struct ListNode));dummyNode->val = -1;dummyNode->next = head;struct ListNode *pre = dummyNode;// 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点// 建议写在 for 循环里,语义清晰for (int i = 0; i < left - 1; i++) {pre = pre->next;}// 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点struct ListNode *rightNode = pre;for (int i = 0; i < right - left + 1; i++) {rightNode = rightNode->next;}// 第 3 步:切断出一个子链表(截取链表)struct ListNode *leftNode = pre->next;struct ListNode *curr = rightNode->next;// 注意:切断链接pre->next = NULL;rightNode->next = NULL;// 第 4 步:同第 206 题,反转链表的子区间reverseLinkedList(leftNode);// 第 5 步:接回到原来的链表中pre->next = rightNode;leftNode->next = curr;return dummyNode->next;
}

 

方法二:一次遍历「穿针引线」反转链表(头插法)

方法一的缺点是:如果 left 和 right 的区域很大,恰好是链表的头节点和尾节点时,找到 left 和 right 需要遍历一次,反转它们之间的链表还需要遍历一次,虽然总的时间复杂度为 O(N)O(N)O(N),但遍历了链表 222 次,可不可以只遍历一次呢?答案是可以的。我们依然画图进行说明。

我们依然以方法一的示例为例进行说明。

整体思想是:在需要反转的区间里,每遍历到一个节点,让这个新节点来到反转部分的起始位置。下面的图展示了整个流程。

下面我们具体解释如何实现。使用三个指针变量 pre、curr、next 来记录反转的过程中需要的变量,它们的意义如下:

curr:指向待反转区域的第一个节点 left;
next:永远指向 curr 的下一个节点,循环过程中,curr 变化以后 next 会变化;
pre:永远指向待反转区域的第一个节点 left 的前一个节点,在循环过程中不变。
第 1 步,我们使用 ①、②、③ 标注「穿针引线」的步骤。

操作步骤:

先将 curr 的下一个节点记录为 next;
执行操作 ①:把 curr 的下一个节点指向 next 的下一个节点;
执行操作 ②:把 next 的下一个节点指向 pre 的下一个节点;
执行操作 ③:把 pre 的下一个节点指向 next。
第 1 步完成以后「拉直」的效果如下:

第 2 步,同理。同样需要注意 「穿针引线」操作的先后顺序。

第 2 步完成以后「拉直」的效果如下:

第 3 步,同理。

第 3 步完成以后「拉直」的效果如下:

struct ListNode *reverseBetween(struct ListNode *head, int left, int right) {// 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论struct ListNode *dummyNode = malloc(sizeof(struct ListNode));dummyNode->val = -1;dummyNode->next = head;struct ListNode *pre = dummyNode;for (int i = 0; i < left - 1; i++) {pre = pre->next;}struct ListNode *cur = pre->next;struct ListNode *next;for (int i = 0; i < right - left; i++) {next = cur->next;cur->next = next->next;next->next = pre->next;pre->next = next;}return dummyNode->next;
}

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

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

相关文章

Linux的一些快捷键(hot keyboard)

Ctrl Alt t&#xff1a;打开bash&#xff08;就是命令框窗口&#xff09; Ctrl Alt F3~F6&#xff1a;打开tty终端&#xff08;纯命令行终端&#xff0c;每个Linux发行版不相同&#xff0c;我的是Ubuntu20版&#xff09; Alt F4&#xff1a;关闭当前窗口&#xff08;Windo…

npm安装yarn

一、关于yarn 有时候使用npm构建项目&#xff0c;拉取第三方库的时候很慢不稳定&#xff0c;而yarn就是解决这一痛点的利器。yarn具有以下优良特性&#xff1a; 1、速度快 Yarn 缓存了每个下载过的包&#xff0c;所以再次使用时无需重复下载&#xff0c; 同时利用并行下载…

知识图谱的广泛应用与价值

目录 前言1 语义搜索2 知识问答2.1 问答对的深度关联2.2 文本挖掘与答案精准性2.3 知识图谱问答的全面服务 3 辅助推荐4 辅助大数据分析4.1 知识图谱推理的应用4.2 知识图谱的数据分析4.3 动态本体技术的引入 5 故障诊断5.1 故障诊断系统的应用5.2 知识图谱在语言理解中的作用5…

【书生·浦语大模型实战营06】《OpenCompass 大模型评测》学习笔记

《OpenCompass 大模型评测》 文档&#xff1a;OpenCompass大模型评测教程 1、主观评测 2、提示词工程 李华每周给2个不同的朋友写一封3页的信&#xff0c;一周写两次。他一年总共写了多少页的信? 李华每周给2个不同的朋友写一封3页的信&#xff0c; 一周写两次。他一年总共…

初识java—java的运算符以及程序逻辑结构

文章目录 算术运算符关系运算符逻辑运算符(重点)逻辑与 &&逻辑 ||逻辑非&#xff01;短路求值&#xff08;重点&#xff09; 程序逻辑控制顺序结构分支结构&#xff08;if else结构&#xff09;switch语句基本语法 循环结构breakcontinue 从键盘输入 算术运算符 基本四…

pygame入门学习(四)位图的使用

大家好&#xff01;我是码银&#x1f970; 欢迎关注&#x1f970;&#xff1a; CSDN&#xff1a;码银 公众号&#xff1a;码银学编程 载入图片 pygame.image.load( )&#xff0c;Pygame 可以通过pygame.image.load( )函数处理位图文件。 大致可以支持以下文件&#xff1a;JPG…

npm run serve和npm run dev的区别

1. 功能&#xff1a;通常&#xff0c;"npm run serve"用于启动开发服务器&#xff0c;提供实时的开发环境&#xff0c;支持自动重新加载和热模块替换。这样可以在开发过程中实时查看代码更改的效果。而"npm run dev"可以是一个自定义的指令&#xff0c;用于…

Linux--文件链接

目录 1.建立软连接 2.建立硬链接 3.什么是软链接 Linux中软链接的应用场景 4.什么是硬链接 5.文件与目录的硬链接数 6.软链接与硬链接的区别 用户无法对目录建立硬链接&#xff0c;可以建立软连接。 在Linux中文件的链接有两种&#xff1a;1.软连接 2.硬链接 1.建立软…

Oracle 高级网络压缩 白皮书

英文版白皮书在这里 或 这里。 本文包括了对英文白皮书的翻译&#xff0c;和我觉得较重要的要点总结。 执行概述 Oracle Database 12 引入了一项新功能&#xff1a;高级网络压缩&#xff0c;作为高级压缩选项的一部分。 本文概述了高级网络压缩、其优点、配置细节和性能分析…

HTML+CSS:3D轮播卡片

效果演示 实现了一个3D翻转的卡片动画&#xff0c;其中每个卡片都有不同的图片和不同的旋转角度。整个动画循环播放&#xff0c;无限次。整个页面的背景是一个占据整个屏幕的背景图片&#xff0c;并且页面内容被隐藏在背景图片之下。 Code <div class"container"…

redis 入门及相关知识汇总

什么是 Redis &#xff1f; 1&#xff0c;相对于mysql &#xff0c;oracle &#xff0c; 这种关系西数据库&#xff0c; 我们还有非关系数据库服务&#xff0c;他的产生是为了&#xff0c;解决常规数据库的并发能力&#xff0c;传统的关系型数据库受限于IO 和性能瓶颈&#xff…

【解决方法】pdf密码忘了怎么办?

PDF文件可以加密&#xff0c;大家都不陌生&#xff0c;并且大家应该也都知道PDF文件有两种密码&#xff0c;一个打开密码、一个限制编辑密码&#xff0c;因为PDF文件设置了密码&#xff0c;那么打开、编辑PDF文件就会受到限制。忘记了PDF密码该如何解密&#xff1f; PDF和offi…

父子组件通信$emit

文章目录 $emit 是vue中用于在子组件向父组件传递消息的一种机制。通过 $emit&#xff0c;子组件可以触发一个自定义事件&#xff0c;并向父组件传递数据。 例如&#xff1a; 以下是使用 $emit 的详细步骤&#xff1a; 1、子组件中触发自定义事件&#xff1a; <!-- ChildCom…

异步编程(JS)

前言 想要学习Promise&#xff0c;我们首先要了解异步编程、回调函数、回调地狱三方面知识&#xff1a; 异步编程 异步编程技术使你的程序可以在执行一个可能长期运行的任务的同时继续对其他事件做出反应而不必等待任务完成。 与此同时&#xff0c;你的程序也将在任务完成后显示…

微服务Spring Cloud架构详解

"Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具&#xff08;例如配置管理&#xff0c;服务发现&#xff0c;断路器&#xff0c;智能路由&#xff0c;微代理&#xff0c;控制总线&#xff09;。分布式系统的协调导致了样板模式, 使用Spring Cloud开…

jupyter notebook删除kernel & conda 删除虚拟环境

jupyter kernelspec list #列出jupyter的所有kernel jupyter kernelspec remove kernel_name #删除特定的kerneljupyter kernelspec list 命令可以在任何激活的环境中运行&#xff0c;无论是 base 环境还是某个虚拟环境。该命令将列出所有已注册的 Jupyter 内核&#xff0c;包括…

技术变革与裁员潮下程序员的挑战与应对策略

引言 一对来自中国的工程师夫妻在美身亡,疑因谷歌裁员致悲剧发生。在技术变革下,裁员对于程序员的影响到底有多大? 技术变革的影响 在当今科技日新月异的时代,技术变革正以前所未有的速度颠覆各行各业。新兴技术如人工智能、云计算、大数据、区块链等不断涌现,对软件工…

Flowable_dmn决策引擎应用

Flowable官方文档 https://www.flowable.com/open-source/docs/dmn/ch02-Configuration 对flowable的bpmn和dmn应用都比较熟悉&#xff0c;前后应用了好几年&#xff0c;年终总结需要这部分&#xff0c;文档就写一下分享给大家&#xff0c;搭建和资源下载参考&#xff1a; flo…

Linux|centos操作系统|USB设备的驱动如何寻找和USB设置的自动挂载,卸载(备忘)

仅做一个记录&#xff0c;Linux命令实在太多了&#xff0c;有些比较有趣的命令还是需要记录一下哈 1&#xff0c; usb-devices命令 该命令会打印输出现有机器上所有的USB设备&#xff0c;此命令等同于cat /sys/kernel/debug/usb/devices 其中部分输出如下&#xff1a; T: …

怎么提升数据分析能力?——功法篇(下)

先来复习一下上篇提到的3个疑问&#xff1a; 为什么我做出来的分析总觉得没有别人的那么高级&#xff1f; 老板为什么总说我的分析“太浅了”&#xff1f; 数据分析师每天的工作就是取数做需求&#xff1f; 看完上篇讲的金字塔原理&#xff0c;如果你还有疑问&#xff0c;不妨再…