【算法专题-链表】反转链表II详解:高频面试题图文解析
创作时间:
作者:
@小白创作中心
【算法专题-链表】反转链表II详解:高频面试题图文解析
引用
CSDN
1.
https://blog.csdn.net/weixin_45031801/article/details/139694781
链表反转是数据结构与算法中的经典问题,尤其在面试中频繁出现。本文详细讲解了如何反转链表中指定区间的节点,通过引入哨兵位头节点简化操作,适合有一定编程基础的读者深入学习。
一、前言
"反转链表II"这道题可以说是链表专题中最经典的一道题,也是面试中频率最高的一道题目。面试官可能会从多个方面考察这道题目,因此大家需要对这道题目非常熟悉。
本篇博客就来详细讲解一下"反转链表II"的实现方法,让我们的面试变得更加顺利!
二、题目描述
给你单链表的头指针 head 和两个整数 left 和 right,其中 left <= right。请你反转从位置 left 到位置 right 的链表节点,返回反转后的链表。
三、解题方法
迭代法 --- 带哨兵位(头节点)
什么是哨兵位头节点?
首先,先来了解一下什么是哨兵位头节点:
- 它是一个附加的链表结点,该结点作为第一个节点,它的数据域不存储任何东西,只是为了操作的方便而引入的。
- 也就是说,如果一个链表有哨兵节点的话,那么链表表的第一个元素应该是链表的第二个节点。
哨兵位头节点的作用:
- 比如向链表中插入一个节点,对于没有哨兵位的单链表,当待插入的节点为链表的第一个节点,由于没有前驱,需要进行特殊处理,从而代码的复杂性增加。
- 如果有哨兵位头节点,则第一个节点的处理方式与其它节点相同,可以统一进行处理。
解题思路
- 这道题,其实就是之前讲过的 ---- 反转链表 --- 的升级版
- 如果我们把要反转的区间抽取出来,看作一个独立的链表,那么其反转的过程与反转链表的过程是一样的。
- 而现在我们比反转链表多了一步是,我们要把抽取出来反转后的区间在拼接回去。
为了把反转后的局部链表拼接回去,我们需要知道四个定位节点: - reversePre: 反转区间的前一个节点
- reverseHead:反转区间的头节点
- reverseTail: 反转区间的尾节点
- reverseNext: 反转区间的下一个节点
我们要把反转后的链表拼接回去,实际上就是让reversePre的next指针指向reverseTail,让reverseHead的next指针指向reverseNext。
- 题目中的left和right的数值分别表示第几个节点,我们可以使用一个变量count来统计当前节点是第几个节点,初始值为1。
- 当反转区间的头节点为head时,head之前没有节点了,为了统一,我们在头节点之前引入哨兵位头节点 --- pre_head。
- 我们从 哨兵位 头节点开始依次遍历节点,直到
count=left
时,刚好到达
reversePre
。
- 然后从
reversePre
的下一个节点开始,即
reverseHead
,依次反转局部链表,直到
count > right
。
- 开始反转局部链表,采用三指针迭代法,可以和之前的 反转链表一样
- 最后将重定向
reversePre
的
next
指针和
reverseHead
的
next
,即将反转后的局部链表重新拼接。
- 最后,返回哨兵位头节点 的 next 指针
代码:
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right)
{
// 创建一个 哨兵位的 头节点 ,并初始化 值域为 0
// 并将 其的 next 指向 head ---- > pre_head->next = head;
ListNode* pre_head = new ListNode(0 , head);
// 定义反转区间 头节点的上一个节点 ,初始先这只为 哨兵尾--pre
ListNode* reversePre = pre_head;
// 节点编号 --- 开始指向 哨兵位 初始值为 1
int count = 1;
// 找到 反转区间 的头节点 的上一个节点
// 注意 left 是从 head 开始计算的哦!
while(count < left)
{
reversePre = reversePre->next;
count++;
}
// 获取 反转区间的 头节点
ListNode* reverseHead = reversePre->next;
// 反转区间 [left , right]
ListNode* last = nullptr;
ListNode* cur = reverseHead;
ListNode* next;
while(count<=right)
{
next = cur->next;
cur->next = last;
last = cur;
cur = next;
count++;
}
// 重新连接反转后的节点
reversePre->next = last; // 反转区间前一个节点应该连接到反转区间的最后一个节点,即当前的last
reverseHead->next = cur; // 反转区间的头节点应该连接到反转区间的下一个节点,即当前的next
// 返回哨兵尾的 下一位
return pre_head->next;
}
};
四、总结与提炼
最后我们来总结一下本文所介绍的内容,本文讲解来一道力扣中有关链表反转的题目,这道题目是校招笔试面试中有关链表章节非常高频的一道题目,大家下去一定要自己再画画图,分析一下,把这段代码逻辑自己实现一遍,才能更好地掌握。
热门推荐
健身时喝牛奶和蛋白粉哪个好?一文详解两者优劣
大学录取分数线详解,了解、规划与成功入学指南
考研焦虑?已经为你准备好了一份超实用的解压秘籍
感冒头晕头重昏昏沉沉是什么原因 应该如何治疗
和好方式指南——如何与天秤座恋人和好(让爱再次升华,以宽容、理解与爱为)
民事诉讼中当事人有权阅卷吗?立案到开庭需要多久?最长结案时间是多久?
巨大儿低血糖要紧吗
嗓子一边疼一边不疼怎么回事
轮台:赏花经济点亮“中国白杏之乡”
二冲程与四冲程汽油机:工作原理之比较及其优劣评估
番禺楼市稳中有进,2024年市场分析
维生素B3(烟酸):血脂天然调节剂
治疗肺大泡的药物有哪些
SQL Server的Descending Indexes降序索引
撸铁每次需要多少次,中间休息多久?今天说说真相!
白银涨跌与哪些因素相关?如何根据这些因素进行白银投资?
百合花的养护技巧
如何降低投资风险
口袋妖怪游戏中蛋孵化的方式、地点、特定版本攻略及特殊宝可梦孵蛋方法
C++程序运行时异常处理:如何精准定位到出错代码行?
“三项改革”让更多“西安智慧”点亮产业星空
通过主板指示灯快速排查电脑故障
漫威:这4个外星种族,齐塔瑞帮助元首,黑寡妇被他们调包!
食品大肠杆菌几种检测方法
伦敦高层住宅的抗震设计标准
看头皮是挂什么科
有按揭的房产相关事宜如何处理?处理这些事宜需要注意什么?
释放潜在性能:玛莎拉蒂总裁刷ECU如何优化驾驶质感
炸酱可以保存多久?炸酱的保存方法与制作技巧详解
岳阳美食探秘:洞庭湖边的味蕾盛宴,让你一口穿越到江南水乡!