【力扣题解】LeetCode 25. K 个一组翻转链表

文章目录


🔥 个人主页:铁皮哥(欢迎关注)

📌 作者简介:28届校招生,后端开发/Agent 方向在学

📚 学习内容:Java、Python、计算机视觉、大语言模型、Agent开发

📝 专栏内容:从零开始的Claude Code零代码生活(持续更新中)

✨不只背八股,更想搞懂为什么这样设计


前言

这道题总是容易卡住,关键是指针有点多,需要考虑的边界有点多,记录一下。

一、题目分析

这道题看上去和 LeetCode 206. 反转链表很相似,实际上 206 就是本题当 k = 链表长度时的情况。

本题核心难点不是"反转链表",而是如何按组反转,并把每一组和前后链表重新接好。

我们可以把链表分成若干段:

上一段尾部 -> 当前要翻转的 k 个节点 -> 下一段头部

每次只处理一组长度为 k 的区间。

假设当前链表是:

dummy -> 1 -> 2 -> 3 -> 4 -> 5

如果 k = 3,当前要翻转的是:

1 -> 2 -> 3

翻转后变成:

3 -> 2 -> 1

然后重新接回原链表:

dummy -> 3 -> 2 -> 1 -> 4 -> 5

这里有几个关键指针:

groupPrev:当前组前一个节点

kth:当前组第 k 个节点

groupNext:当前组后面的第一个节点

二、解法

题目最终要返回头节点,我们先在 head 前自行接一个 dummy 节点,最后我们返回的答案就是 dummy.next

java 复制代码
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;

        return dummy.next;
        
    }
}

来看之前提到的关键指针 groupPrev,最开始应该被这样初始化,因为第一组的前一个结点就是 dummy

java 复制代码
ListNode groupPrev = dummy;

下一步我们要扩一个大循环,在里面完成 k 个一组的翻转链表,具体是这样的思路:

java 复制代码
while(true){
//1. 找到当前翻转组的第 K 个结点,即关键结点 kth
//第 K 个结点的下一个结点就是关键结点 groupNext

//2.按照力扣 206 的思路去翻转从 groupPrev.next 到 kth 的链表

//3.把翻转后的链表正确接回原链表
           
}

先来实现找到第 k 个结点的方法,这里很简单,就是逐层 k--,直到 k = 0node 先变成 null 的时候退出。要考虑:node == null 其实就意味着剩余结点数量已经不足 k 个了,可以退出主函数中的大循环了。

java 复制代码
private ListNode getKth(ListNode node, int k){
	while(node != null && k != 0){
		node = node.next;
		k--;
	}
	return node;
}

所以循环 while(true) 的终止条件,肯定是当剩余链表的数量已经不足 k 个时退出,可以写成这样:

java 复制代码
ListNode kth = getKth(groupPrev, k);
if(kth == null){
	break;
}

下一步去翻转从 groupPrev.nextkth 的链表。
groupNext 的语义是当前组的下一个结点。

其他操作就和力扣 206 的思路是一样的,唯一不同的是 while 的终止条件不是 cur != null,而是 cur != groupNext,这是因为我们最多只能翻转 k 个结点,如果终止条件设为 cur != null,那就会翻转从当前一直到尾部的所有结点了。

java 复制代码
ListNode groupNext = kth.next;
ListNode prev = groupNext;
ListNode cur = groupPrev.next;
while(cur != groupNext){
	ListNode temp = cur.next;
	cur.next = prev;
	prev = cur;
	cur = temp;
}

翻转完这 k 个结点后,下一步是把当前处理好的结点组接回原链表。

oldGroupHead 指向的是"翻转前"的当前组的头结点,目前已经变成了当前组的尾结点,先把这个值暂存起来。
kth 经过翻转,已经从原先的尾结点变成了当前组的新头结点,所以 groupPrev.next = kth 的意思是:让该组前一个节点的 next 指向这个新的头结点。

然后再把 groupPrev 移动到之前暂存的 oldGroupHead,因为它现在是当前组的尾结点,下一轮要从它后面继续处理。

java 复制代码
ListNode oldGroupHead = groupPrev.next;
groupPrev.next = kth;
groupPrev = oldGroupHead;

最终整体代码呈现如下:

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;

        ListNode groupPrev = dummy;
        while(true){
            ListNode kth = getKth(groupPrev, k);
            if(kth == null){
                break;
            }
            ListNode groupNext = kth.next;
            ListNode prev = groupNext;
            ListNode cur = groupPrev.next;
            while(cur != groupNext){
                ListNode temp = cur.next;
                cur.next = prev;
                prev = cur;
                cur = temp;
            }
            ListNode oldGroupHead = groupPrev.next;
            groupPrev.next = kth;
            groupPrev = oldGroupHead;

        }

        return dummy.next;
        
    }
    private ListNode getKth(ListNode node, int k){
        while(node != null && k != 0){
            node = node.next;
            k--;
        }
        return node;
    }
}

写在文后

期待您的一键三连!如果有什么问题或建议欢迎在评论区交流!

相关推荐
兵慌码乱4 小时前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
朦胧之5 小时前
AI 编程-老项目改造篇
java·前端·后端
金銀銅鐵5 小时前
[Python] 体验用欧几里得算法计算最大公约数的过程
python·数学
FreakStudio9 小时前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
kisshyshy9 小时前
🍦 雪糕、食堂、火车厢:三幅漫画吃透栈、队列与链表
javascript·算法
程序猿大帅9 小时前
别再只当调包侠了:用 Spring AI 落地 Function Calling,我被大模型硬生生砸出了三个大坑
java
用户03321266636710 小时前
使用 Python 从零创建 Word 文档
python
程序员晓琪10 小时前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly10 小时前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring
众少成多积小致巨11 小时前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++