LeetCode Hot 100 —— 25. K 个一组翻转链表
本文最后更新于79 天前,其中的信息可能已经过时,如有错误请发送邮件到mocic1ovo@gmail.com

题目链接:25. K 个一组翻转链表

题目要求我们每 k 个节点为一组进行翻转,如果最后剩余的节点数量不足 k,则保持原有顺序不变。

这道题的难点并不在于“翻转链表”本身,而在于如何正确处理每一组之间的连接关系,以及如何在多次翻转过程中保证指针始终合法。


一、整体思路

可以将问题拆分成两个部分:

  1. 如何翻转一段指定区间的链表
  2. 如何按 k 个节点一组,循环处理整条链表

二、区间翻转的设计

我们定义一个函数,用来翻转从 headtail 的这一段链表,并返回翻转后的新头和新尾。

函数签名

pair<ListNode*,ListNode*> myRe(ListNode* head, ListNode* tail)

翻转核心思路

  • prev 指向 tail->next,作为翻转后的终止位置
  • head 开始逐个反转指针
  • prev == tail 时,翻转结束

代码实现

pair<ListNode*,ListNode*> myRe(ListNode* head, ListNode* tail){
    ListNode* prev = tail -> next;
    ListNode* p = head;
    while(prev != tail){
        ListNode* ne = p -> next;
        p -> next = prev;
        prev = p;
        p = ne;
    }
    return {tail, head};
}

翻转完成后:

  • 原来的 tail 变成新的 head
  • 原来的 head 变成新的 tail

三、主函数整体框架

引入虚拟头节点

ListNode* hair = new ListNode(0);
hair -> next = head;
ListNode* pre = hair;

引入虚拟头节点 hair,可以统一处理头节点翻转的情况,避免额外的边界判断。


四、按 k 个节点一组遍历

while(head){
    ListNode* tail = pre;
    for(int i = 0;i < k; i++){
        tail = tail -> next;
        if(!tail){
            return hair -> next;
        }
    } 

这一步用于判断:

  • 当前剩余链表长度是否不少于 k
  • 如果不足 k,直接返回结果

五、翻转并重新连接链表

ListNode* nex = tail -> next;
tie(head, tail) = myRe(head,tail);
pre -> next = head;
tail -> next = nex;

操作顺序非常关键:

  1. 记录 tail->next,防止链表断裂
  2. 翻转当前区间
  3. 将翻转后的新头接到 pre 后面
  4. 将翻转后的新尾接回剩余链表

六、移动指针,进入下一轮

pre = tail;
head = tail -> next; 

此时:

  • pre 移动到当前翻转后的尾节点
  • head 指向下一组的起始位置

七、完整代码

class Solution {
public:
    pair<ListNode*,ListNode*> myRe(ListNode* head,ListNode* tail){
        ListNode* prev = tail -> next;
        ListNode* p = head;
        while(prev != tail){
            ListNode* ne = p -> next;
            p -> next = prev;
            prev = p;
            p = ne;
        }
        return {tail,head};
    }

    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* hair = new ListNode(0);
        hair -> next = head;
        ListNode* pre = hair;

        while(head){
            ListNode* tail = pre;
            for(int i = 0;i < k; i++){
                tail = tail -> next;
                if(!tail){
                    return hair -> next;
                }
            } 
            ListNode* nex = tail -> next;
            tie(head, tail) = myRe(head,tail);
            pre -> next = head;
            tail -> next = nex;
            pre = tail;
            head = tail -> next; 
        }

        return hair -> next;
    }
};
转载请注明文章地址及作者喔

评论

  1. 筱乐
    Windows Edge
    3 月前
    2025-12-15 20:01:00

    干货满满

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇