LeetCode 面试经典 150_链表_反转链表 II(60_92_C++_中等)(头插法) - 教程

news/2025/11/23 14:03:07/文章来源:https://www.cnblogs.com/yangykaifa/p/19260515

LeetCode 面试经典 150_链表_反转链表 II(60_92_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

题解:

解题思路:

思路一(头插法):

1、创建一个 dummyHead(伪头节点),保存链表头。

  • left 结点之前的结点无需翻转,首先定位到left位置的结点,并保存left前的一个结点信息为 pre,left结点信息为leftNode。
  • 从left位置采用头插法插入pre结点之后。直至插入到right结点。
  • 将right右侧结点连接到leftNode后

例: head = [1,2,3,4,5], left = 2, right = 4
1、定位left位置,leftNode=2,pre =1。dummyHead->1
2、从 2 开始采用头插法插入 1 之后,到right结束 ,dummyHead->1->4->3->2
3、将right右侧结点连接到leftNode后, dummyHead->1->4->3->2->5->nullptr

2、复杂度分析:
① 时间复杂度:O(n),n 代表链表中元素的个数,只遍历了一遍列表。
② 空间复杂度:O(1),使用常数个内存空间(只对源节点的next指向进行更改)。

代码实现

代码实现(思路一(头插法)):
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
// 如果链表为空,或反转区间没有变化(left == right),直接返回原链表
if (!head || left == right){
return head;
}
// 创建虚拟头节点,简化处理,指向链表的头节点
ListNode *dummyHead = new ListNode(0, head);
ListNode *curNode = head;  // 当前节点从链表的头开始
ListNode *pre = dummyHead; // pre指向虚拟头节点
// 1. 定位到反转区间的前一个节点(即位置 left-1)
for (int i = 1; i < left; i++) {
pre = pre->next;          // pre移到left-1位置
curNode = curNode->next;  // curNode移到left位置
}
// 2. 保存反转区域的起始节点
ListNode *leftNode = curNode;
ListNode *nextNode = nullptr;  // 用于暂存当前节点的下一个节点
// 3. 反转从left到right的部分
for (int i = left; i <= right; i++) {
nextNode = curNode->next;   // 记录当前节点的下一个节点
curNode->next = pre->next;  // 当前节点指向pre->next
pre->next = curNode;        // pre->next指向当前节点
curNode = nextNode;         // 当前节点移到下一个节点
}
// 4. 连接反转后的部分与剩余部分
leftNode->next = curNode;  // 将反转区域的尾节点连接到剩余部分
// 5. 返回新的链表头,虚拟头节点的next就是新链表的头
ListNode *ans = dummyHead->next;
// 删除虚拟头节点,避免内存泄漏
delete dummyHead;
return ans;  // 返回新链表的头节点
}
};
以思路一为例进行调试
#include<iostream>#include<vector>using namespace std;struct ListNode{int val;ListNode *next;ListNode():val(0),next(nullptr){}ListNode(int x):val(x),next(nullptr){}ListNode(int x,ListNode *next):val(0),next(next){}};//尾插法创建链表ListNode *createList(vector<int> nums){ListNode *head=nullptr,*tail=nullptr;for (auto &num : nums){if (head==nullptr){head=tail=new ListNode(num);}else{tail->next=new ListNode(num);tail=tail->next;}}return head;}/** 头插法* 首先定位到left位置的结点,并保存left前的一个结点信息为 pre,left结点信息为leftNode。* 从left位置采用头插法插入pre结点之后。直至插入到right结点。* 将right右侧结点连接到leftNode后* 例子:head = [1,2,3,4,5], left = 2, right = 4* 1、定位left位置,leftNode=2,pre =1。dummyHead->1* 2、从 2 开始采用头插法插入 1 之后,到right结束 ,dummyHead->1->4->3->2* 3、将right右侧结点连接到leftNode后, dummyHead->1->4->3->2->5->nullptr**/class Solution {public:ListNode* reverseBetween(ListNode* head, int left, int right) {// 如果链表为空,或反转区间没有变化(left == right),直接返回原链表if (!head || left == right){return head;}// 创建虚拟头节点,简化处理,指向链表的头节点ListNode *dummyHead = new ListNode(0, head);ListNode *curNode = head;  // 当前节点从链表的头开始ListNode *pre = dummyHead; // pre指向虚拟头节点// 1. 定位到反转区间的前一个节点(即位置 left-1)for (int i = 1; i < left; i++) {pre = pre->next;          // pre移到left-1位置curNode = curNode->next;  // curNode移到left位置}// 2. 保存反转区域的起始节点ListNode *leftNode = curNode;ListNode *nextNode = nullptr;  // 用于暂存当前节点的下一个节点// 3. 反转从left到right的部分for (int i = left; i <= right; i++) {nextNode = curNode->next;   // 记录当前节点的下一个节点curNode->next = pre->next;  // 当前节点指向pre->nextpre->next = curNode;        // pre->next指向当前节点curNode = nextNode;         // 当前节点移到下一个节点}// 4. 连接反转后的部分与剩余部分leftNode->next = curNode;  // 将反转区域的尾节点连接到剩余部分// 5. 返回新的链表头,虚拟头节点的next就是新链表的头ListNode *ans = dummyHead->next;// 删除虚拟头节点,避免内存泄漏delete dummyHead;return ans;  // 返回新链表的头节点}};int main(int argc, char const *argv[]){vector<int> nums={1,2,3,4,5};ListNode *head=createList(nums);int left=2;int right=4;//验证二叉树是否创建成功// while (head!=nullptr){//     cout<<head->val<<" ";//     head=head->next;// }Solution s;ListNode *ans = s.reverseBetween(head,left,right);while (ans!=nullptr){cout<<ans->val<<" ";ans=ans->next;}return 0;}

LeetCode 面试经典 150_链表_反转链表 II(60_92)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

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

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

相关文章

ubuntu22.04 源更新报错 —— all.deb 403 Forbidden [IP: 101.6.15.130 80

ubuntu22.04 源更新报错 —— all.deb 403 Forbidden [IP: 101.6.15.130 80备份源文件sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak 更改为清华大学源用编辑器打开 /etc/apt/sources.list 参考 :http://…

【ESP32】VSCode PlatformIO第一次初始化项目卡死

第一次安装platformio后点击下面图片的 finish 按钮等待创建第一个项目, 然后就一直转圈:国内的最大可能就是网络问题,根据网上资料, platformio使用了自己的虚拟环境, 所以现在唯一的目标就是找到这个虚拟环境配置代…

完整教程:【Linux入门】常用工具:yum、vim

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025宠物饮水机水泵品牌TOP5推荐,水暖毯水泵、加湿器水泵、冷风扇水泵等微型水泵厂商品质性价比选择指南

随着智能家居与宠物用品市场的快速扩张,水泵作为核心流体控制部件,其技术性能与品质稳定性成为行业竞争的关键。本榜单基于产品创新力、技术适配性、市场认可度三大维度(中山市海宝电器新增“多领域应用”维度),结…

2025水暖毯水泵品牌TOP5推荐,宠物饮水机水泵、加湿器水泵、冷风扇水泵等微型水泵厂商品质性价比选择指南

随着智能家居与宠物用品市场的快速扩张,水泵作为核心流体控制部件,其技术性能与品质稳定性成为行业竞争的关键。本榜单基于产品创新力、技术适配性、市场认可度三大维度(中山市海宝电器新增“多领域应用”维度),结…

【Kubernetes】集成ELK收集日志

Kubernetes集成ELK日志 由于我们使用Helm部署ELK,这里将分别部署Elasticsearch、Kibana和Logstash。同时,我们还需要部署Filebeat作为日志收集器 步骤:添加Elastic Helm仓库 部署Elasticsearch 部署Kibana 部署Logs…

2025防脱洗护品牌最新TOP5实测推荐:老姜王+草本双核心,洗发水+按摩

​​随着消费者对天然洗护理念的深入追求,草本防脱洗发水市场迎来爆发式增长。本榜单基于成分天然度、防脱效果、头皮适配性、用户口碑四大维度,结合《2025中国洗护用品消费趋势报告》及第三方检测机构数据,权威解析…

2025草本防脱洗护品牌怎么选?名花贵族(大宏生物),以植萃力量,重新定义头皮健康养护,老姜王防脱洗发水、头皮按摩膏,效果明显,口碑推荐

在当代快节奏生活中,脱发、头痒、头油等头皮问题已成为困扰国民健康的重要议题。据《中国头皮健康白皮书》数据显示,我国2.5亿脱发人群中,25-35岁青壮年占比达63%,头皮敏感问题发生率较十年前上升27%。在此背景下,…

2025草本洗护哪个品牌效果最好?老姜王防脱、草本洗发水、头皮按摩膏十大品牌测评推荐

随着现代生活节奏加快,工作压力增大,长期熬夜、饮食不规律等问题导致我国超60%的成年人存在头皮敏感、头油头痒、发丝干枯,以及肌肤干燥、易过敏等亚健康状态。在日常洗护场景中,传统化学合成洗护产品虽清洁力强,…

ios17可自动清除短信验证码吗安全吗

可以。二、自动清除短信验证码的方法iOS 17 系统更新包括一个新选项,可以在通过自动填充功能将消息(和邮件)中的验证码插入 App 或网站后删除验证码。用户可以在【密码选项】下的【密码】应用中为验证码打开【自动清理…

iOS 虚拟现实开发怎样简化开发流程

在iOS上进行虚拟现实(VR)开发可能会遇到一些挑战,但通过使用合适的工具、框架和最佳实践,可以有效地简化开发流程。以下是一些建议,可以帮助你简化iOS虚拟现实开发的流程: 使用高效的开发工具和框架虚幻引擎5:对…

iOS 虚拟现实开发怎样应对高帧率

在iOS虚拟现实开发中,应对高帧率是一个重要的挑战,因为它直接影响到用户的体验和沉浸感。以下是一些有效的策略和技术,可以帮助开发者优化iOS虚拟现实应用的性能,以支持高帧率: 加速传感器优化优化采样率:根据应…

实用指南:【开发者导航】集成多引擎与离线查询的macOS开源翻译工具:Easydict

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

微信小程序 分享功能

/*** 用户点击右上角分享*/onShareAppMessage: function () {const pages = getCurrentPages();const currentPage = pages[pages.length - 1];return this.getPageShareInfo(currentPage);},onShareTimeline : funct…

微软Dynamics 365 CRM从入门到就业之路的规划

长沙爱码士IT给我们的一个学习进阶就业的规划如下:,聚焦微软 Dynamics 365 CRM 与 Power Platform 生态的实战型,主打从零基础到高薪就业的全链路培养,适配应届生、转行人群等想要进入 IT 咨询领域的学习者,以下是…

iOS 虚拟现实开发怎样优化体验

iOS 虚拟现实开发可以通过多种方式优化体验,以下是一些关键的策略和技术: 性能优化几何体优化:移除用户看不到的几何体面,简化模型设计,减少不必要的细节。 纹理和材质优化:使用纹理贴图集,避免使用normal maps…

LiveCD镜像

puppy镜像简介 Puppy Linux is a unique family of Linux distributions meant for the home-user computers. It was originally created by Barry Kauler in 2003. Puppy Linux是专用于家庭用户计算机的独特Linux发行…

最轻量的图片处理工具:一个可以很方便地添加文字和裁剪图片的.html

点击Chrome工具栏上的截图—区域截图—编辑,就能写字、画框、画线,缩放、填充。 但它不能改文字大小和字体。我这个可以。还能裁剪图片。 添加后的文字可用鼠标拖拽。多一个width: 1em,文字就竖着写了:玩法很多。H…

依旧面向对象Java基础学习

依旧Java基础学习final用final修饰类,则类不能被继承 用final修饰方法,则方法不能被重写 用final修饰变量,则变量仅能被赋值一次单例设计模式(一个类只有一个对象) //饿汉式单例类 public class A{//1.私有构造器…

Oracle数据库密码过期问题终极解决方案:期限取消+用户解锁+原密码保留

Oracle数据库密码过期问题终极解决方案:期限取消+用户解锁+原密码保留合集 - Oracle(36)1.实战!oracle 11g一键安装脚本分享2024-10-142.Oracle数据库七种闪回技术详解与实践示例10-313.Oracle ADG 切换方式详解:Sw…