【算法专题--链表】反转链表II--高频面试题(图文详解,小白一看就会!!!)

目录

一、前言

二、题目描述

三、解题方法

[⭐迭代法 --- 带哨兵位(头节点)](#⭐迭代法 --- 带哨兵位(头节点))

[🥝 什么是哨兵位头节点?](#🥝 什么是哨兵位头节点?)

[🍍 解题思路](#🍍 解题思路)

四、总结与提炼

五、共勉


一、前言

反转链表II这道题,可以说是--链表专题 --,最经典 的一道题,也是在面试中频率最高的一道题目,通常在面试中,面试官可能会从多个方面考察这道题目,所以大家需要对这道题目非常熟悉哦!!
本片博客就来详细的讲讲解一下 反转链表II 的实现方法,让我们的面试变的更加顺利!!!

二、题目描述

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

三、解题方法

⭐迭代法 --- 带哨兵位(头节点)

🥝 什么是哨兵位头节点?

首先,先来了解一下什么是 哨兵位---头节点

  • 它是一个附加的链表结点,该 结点 作为第一个节点,它的数据域不存储任何东西,只是为了操作的方便而引入的。
  • 也就是说,如果一个链表有哨兵节点的话 ,那么链表表的第一个元素应该是链表的第二个节点。

哨兵位 --- 头节点的作用:

  • 比如向链表中插入一个节点,对于没有哨兵位单链表当待插入的节点为链表的第一个节点,由于没有前驱,需要进行特殊处理,从而代码的复杂性增加。
  • 如果有哨兵位头节点,则第一个节点的处理方式与其它节点相同,可以统一进行处理

🍍 解题思路

  • 这道题,其实就是之前讲过的 ---- 反转链表 --- 的升级版
  • 如果我们把要 反转的区间 抽取出来,看作一个独立的链表,那么其反转的过程与反转链表的过程是一样的。
  • 而现在我们比 反转链表 多了一步是,我们要把抽取出来反转后的区间在拼接回去

为了把反转后的局部链表拼接回去,我们需要知道四个定位节点:

  • **reversePre:**反转区间的前一个节点
  • **reverseHead:**反转区间的头节点
  • **reverseTail:**反转区间的尾节点
  • **reverseNext:**反转区间的下一个节点

我们要把反转后的链表拼接回去,实际上就是让 reversePrenext指针 指向 reverseTail,让reverseHeadnext指针 指向 reverseNext。

  • 题目中的 leftright 的数值分别表示第几个节点,我们可以使用一个变量 count来统计当前节点是第几个节点,初始值为1
  • 当反转区间的头节点为head 时,head之前没有节点了,为了统一,我们在头节点之前引入哨兵位头节点 --- pre_head
  • 我们从 哨兵位 头节点开始依次遍历节点,直到 count=left 时,刚好到达 reversePre
  • 然后从 reversePre 的下一个节点开始,即 reverseHead,依次反转局部链表,直到 count > right
  • 开始反转局部链表,采用三指针迭代法,可以和之前的 反转链表 一样
  • 最后将重定向 reversePre next指针reverseHeadnext,即将反转后的局部链表重新拼接。
  • 最后,返回 哨兵位头节点 的 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;

    }
};

四、总结与提炼

最后我们来总结一下本文所介绍的内容,本文讲解来一道力扣中有关链表反转的题目,这道题目是 校招笔试面试中有关链表章节非常高频的一道题目**,** 大家下去一定要自己再画画图,分析一下,把这段代码逻辑自己实现一遍,才能更好地掌握

五、共勉

以下就是我对 反转链表II 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对 链表专题 的理解,请持续关注我哦!!!

相关推荐
R-G-B1 分钟前
【06】C#入门到精通——C# 多个 .cs文件项目 同一项目下添加多个 .cs文件
开发语言·c#·c# 多个 .cs文件项目
xwl121224 分钟前
10.6 作业
数据结构·算法
青草地溪水旁24 分钟前
VSCode C/C++ 构建任务配置文件 `tasks.json` 全字段深度解析
c语言·c++·vscode
数据知道24 分钟前
Go基础:正则表达式 regexp 库详解
开发语言·mysql·golang·正则表达式·go语言
小蒜学长25 分钟前
jsp基于JavaWeb的原色蛋糕商城的设计与实现(代码+数据库+LW)
java·开发语言·数据库·spring boot·后端
zhangfeng113329 分钟前
亲测可用,R语言 ggplot2 箱线图线条控制参数详解,箱线图离散数值控制
开发语言·python·r语言·生物信息
yzx99101329 分钟前
国庆科技感祝福:Python 粒子国旗动画
开发语言·人工智能·python
代码改善世界37 分钟前
【C语言操作符终极指南】万字总结:从二进制到表达式求值,全方位解析+避坑指南
c语言
迪丽热爱38 分钟前
【练】C程序设计-01程序设计和C语言
c语言·开发语言
扶尔魔ocy38 分钟前
【QT常用技术讲解】opencv实现摄像头图像检测并裁剪物体
开发语言·qt·opencv