【力扣题解】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;
    }
}

写在文后

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

相关推荐
Starmoon_dhw4 分钟前
题解:P16108 「o.OI R-1」基础博弈练习题
c++·算法·图论
@陈小鱼15 分钟前
MATLAB+Python:基于小样本卷积神经网络的 PPG 血压预测
人工智能·python·机器学习·matlab·脉搏波·血压·一维卷积神经网络
亦暖筑序15 分钟前
AgentScope-Java 入门:用 SSE 展示评审任务进度
java·agent·ai编程
大鱼>17 分钟前
AI+快递分拣:视觉识别+自动分拣+异常检测
人工智能·深度学习·算法·机器学习
想要成为糕糕手19 分钟前
238. 除了自身以外数组的乘积 — 面试向深度解析
javascript·算法·面试
卷无止境23 分钟前
Python数据进阶专题:用声明式验证让数据管道告别"惊喜"
后端·python·数据分析
卓怡学长29 分钟前
w261springboot基于web学校课程管理系统
java·数据库·spring boot·spring·intellij-idea
shuoshuohaohao30 分钟前
《JavaWeb --2》
java
浩瀚地学31 分钟前
【面试算法笔记】0105-数组-螺旋矩阵
java·开发语言·笔记·算法·面试
AI人工智能+电脑小能手38 分钟前
【大白话说Java面试题 第169题】【07_Redis篇】第5题:如何保证缓存一致性?
java·redis·延迟双删·缓存一致性·双写一致性