目录
一、前言
二、题目描述
三、解题方法
⭐双指针 -- 采用哨兵位头节点
🥝 什么是哨兵位头节点?
🍍 案例图解
四、总结与提炼
五、共勉
一、前言
K个一组翻转链表 这道题,可以说是--链表专题--,最经典的一道题,也是在面试中频率最高的一道题目,通常在面试中,面试官可能会从多个方面考察这道题目,所以大家需要对这道题目非常熟悉哦!!
本片博客就来详细的讲讲解一下 K个一组翻转链表 的实现方法,让我们的面试变的更加顺利!!!
二、题目描述
题目连接:25. K 个一组翻转链表 - 力扣(LeetCode)
三、解题方法
⭐双指针 -- 采用哨兵位头节点
🥝 什么是哨兵位头节点?
首先,先来了解一下什么是 哨兵位---头节点 ?
- 它是一个附加的链表结点,该 结点 作为 第一个节点,它的数据域不存储任何东西,只是为了操作的方便而引入的。
- 也就是说,如果一个链表有哨兵节点的话,那么链表表的第一个元素应该是链表的第二个节点。
哨兵位 --- 头节点的作用:
- 比如向链表中插入一个节点,对于没有哨兵位的单链表,当待插入的节点为链表的第一个节点,由于没有前驱,需要进行特殊处理,从而代码的复杂性增加。
- 如果有哨兵位头节点,则第一个节点的处理方式与其它节点相同,可以统一进行处理。
🍍 解题思路
根据题目要求,我们需要将链表中每
k
个节点翻转。我们先统计链表中的节点数,然后每k
个节点作为一组,在这一组中进行链表翻转,翻转后我们利用一个节点p0
将已经翻转的节点和接下来将要翻转的节点沟通起来。
🍍 案例图解
链表:【1,2,3,4,5】
- 创建 哨兵位头节点 和 双指针,开始遍历整个链表,并统计链表的节点个数 count = 5
- 在外循环1 中,我们可以根据 反转链表 中讲过的三指针法,先将第一组的链表翻转,接着 更新指针 p0 ,指向第二组链表的头节点,同理可以得到 外循环 2 的结果
复杂度分析 :
时间复杂度:O ( n ),n 为链表的节点个数
空间复杂度:O ( 1 )
代码:
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k)
{
// 反转链表(三指针) + 哨兵位
// 创建一个哨兵位 初始化为 -1,连接到 head 上
ListNode* pre_head = new ListNode(-1,head);
ListNode* p0 = pre_head; // 用于连接反转后的链表
// 统计链表有多少个节点
int count = 0;
ListNode* cur = head;
while(cur)
{
cur = cur->next;
count++;
}
// 开始进行分组反转 -- 三指针法
ListNode* pre = nullptr;
cur = head;
for(int n = count ; n>=k ; n = n-k)
{
// 反转局部链表,反转 k 个节点
for(int i = 0; i < k ; i++)
{
ListNode* nextnode = cur->next;
cur->next = pre;
pre = cur;
cur = nextnode;
}
// 将反转的节点 和 要反转的的节点沟通起来
ListNode* next = p0->next;
p0->next->next = cur;
p0->next = pre;
p0 = next;
}
// 返回哨兵位的 下一个节点
return pre_head->next;
}
};
四、总结与提炼
最后我们来总结一下本文所介绍的内容,本文讲解来一道力扣中有关 K个一组翻转链表的题目,这道题目是校招笔试面试中有关链表章节非常高频的一道题目,大家下去一定要自己再画画图,分析一下,把这段代码逻辑自己实现一遍,才能更好地掌握
五、共勉
以下就是我对 K个一组翻转链表 的理解,如果有不懂和发现问题的小伙伴,请在评论区说出来哦,同时我还会继续更新对 链表专题 的理解,请持续关注我哦!!!