news 2026/6/30 18:04:09

【每日算法】LeetCode 25. K 个一组翻转链表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【每日算法】LeetCode 25. K 个一组翻转链表

对前端开发者而言,学习算法绝非为了“炫技”。它是你从“页面构建者”迈向“复杂系统设计者”的关键阶梯。它将你的编码能力从“实现功能”提升到“设计优雅、高效解决方案”的层面。从现在开始,每天投入一小段时间,结合前端场景去理解和练习,你将会感受到自身技术视野和问题解决能力的质的飞跃。------ 算法:资深前端开发者的进阶引擎

LeetCode 25. K 个一组翻转链表

1. 题目描述

给你链表的头节点head,每k个节点一组进行翻转,请你返回修改后的链表。

如果节点总数不是k的整数倍,最后剩余的节点保持原有顺序。

示例1:

输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5]

示例2:

输入:head = [1,2,3,4,5], k = 3 输出:[3,2,1,4,5]

说明:

  • 链表中的节点数目为n
  • 1 <= k <= n <= 5000
  • 0 <= Node.val <= 1000

2. 问题分析

这道题的核心是链表操作,前端开发者经常处理类似结构:

  • DOM树节点操作(如批量重新排序元素)
  • 虚拟DOM的diff算法中节点位置调整
  • 数据流处理中的分批操作
  • 实现分页、轮播等组件时的节点管理

关键难点:

  1. 需要精确控制指针的指向关系
  2. 处理边界情况(不足k个的情况)
  3. 保持翻转后的正确连接
  4. 需要保存关键节点位置以便后续连接

3. 解题思路

3.1 递归法(清晰直观)

时间复杂度:O(n),空间复杂度:O(n/k)(递归栈深度)

  • 递归处理每k个节点
  • 翻转当前k个节点后,递归处理后续部分
  • 将翻转后的子链表连接起来

3.2 迭代法(最优解)

时间复杂度:O(n),空间复杂度:O(1)

  • 使用虚拟头节点简化操作
  • 分组遍历并翻转每一组
  • 维护关键指针:前驱节点、当前组头、当前组尾
  • 处理不足k个的情况

最优解:迭代法,因为它在O(n)时间内解决问题,且只使用常数级额外空间。

4. 代码实现

4.1 递归实现

/** * 递归解法 * 时间复杂度:O(n),空间复杂度:O(n/k)(递归调用栈) */constreverseKGroupRecursive=function(head,k){// 检查是否有k个节点可供翻转letcurr=head;letcount=0;// 检查剩余节点是否足够k个while(curr!==null&&count<k){curr=curr.next;count++;}// 如果不足k个,直接返回当前头节点if(count<k){returnhead;}// 翻转当前k个节点letprev=null;letcurrent=head;for(leti=0;i<k;i++){constnext=current.next;current.next=prev;prev=current;current=next;}// 递归处理后续部分,并将当前翻转后的尾节点连接到后续结果head.next=reverseKGroupRecursive(current,k);// prev现在是翻转后的新头节点returnprev;};

4.2 迭代实现(最优)

/** * 迭代解法(最优解) * 时间复杂度:O(n),空间复杂度:O(1) */constreverseKGroup=function(head,k){// 创建虚拟头节点,简化边界处理constdummy=newListNode(0);dummy.next=head;// pre指向当前要翻转的链表的前一个节点letpre=dummy;while(head){// tail指向当前要翻转的链表的尾部lettail=pre;// 查看剩余部分长度是否大于等于kfor(leti=0;i<k;i++){tail=tail.next;if(!tail){// 不足k个,直接返回结果returndummy.next;}}// next指向下一个要翻转的链表头constnextGroup=tail.next;// 翻转当前k个节点,返回翻转后的头尾节点const[newHead,newTail]=reverseList(head,tail);// 把翻转后的子链表重新接回原链表pre.next=newHead;newTail.next=nextGroup;// 更新pre和head,准备下一轮翻转pre=newTail;head=nextGroup;}returndummy.next;};/** * 辅助函数:翻转从head到tail的链表 * 返回翻转后的新头节点和新尾节点 */constreverseList=function(head,tail){letprev=tail.next;// 关键:连接到下一组的头letcurr=head;while(prev!==tail){constnext=curr.next;curr.next=prev;prev=curr;curr=next;}// 翻转后,tail成为新头,head成为新尾return[tail,head];};

4.3 可读性更好的迭代实现(适合前端理解)

/** * 更易理解的迭代解法 * 将翻转逻辑拆解为更小的函数 */constreverseKGroupEasy=function(head,k){// 计算链表长度constgetLength=(node)=>{letlen=0;while(node){len++;node=node.next;}returnlen;};// 翻转链表的一部分constreversePart=(start,end)=>{letprev=end.next;// 连接到下一组的头letcurr=start;while(prev!==end){constnext=curr.next;curr.next=prev;prev=curr;curr=next;}return[end,start];// 返回新头和新尾};constlength=getLength(head);constdummy=newListNode(0);dummy.next=head;letprev=dummy;// 计算可以翻转多少组constgroups=Math.floor(length/k);for(leti=0;i<groups;i++){// 定位当前组的头和尾letgroupHead=prev.next;letgroupTail=prev;for(letj=0;j<k;j++){groupTail=groupTail.next;}// 下一组的头constnextGroup=groupTail.next;// 翻转当前组const[newHead,newTail]=reversePart(groupHead,groupTail);// 重新连接prev.next=newHead;newTail.next=nextGroup;// 更新prev,准备下一组prev=newTail;}returndummy.next;};

5. 复杂度对比分析

方法时间复杂度空间复杂度优点缺点
递归法O(n)O(n/k) 递归栈空间代码简洁,逻辑清晰递归栈可能溢出,空间复杂度较高
迭代法(最优)O(n)O(1)空间效率高,适合处理长链表指针操作复杂,容易出错
改进迭代法O(n)O(1)逻辑更清晰,易于理解和维护需要额外计算链表长度

性能总结:

  • 迭代法是最优选择,尤其对于大规模数据
  • 递归法在k值较小时表现良好,代码更简洁
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/28 21:56:23

SQL语言家族入门指南:标准SQL、T-SQL与PL/SQL详解

SQL语言家族入门指南&#xff1a;标准SQL、T-SQL与PL/SQL详解 对于数据库初学者来说&#xff0c;SQL语言的各种变体常常让人困惑。本文将为你详细解析标准SQL、T-SQL和PL-SQL的概念及其应用场景。 标准SQL 概念 标准SQL (Structured Query Language) 是由ANSI和ISO标准化组织制…

作者头像 李华
网站建设 2026/6/30 3:38:00

Thymeleaf 项目创建及请求响应过程解析

创建项目 1. 使用Spring Initializr创建项目 访问 https://start.spring.io/ 或使用IDE的Spring Initializr功能&#xff0c;选择以下依赖&#xff1a; Spring WebThymeleafSpring Boot DevTools&#xff08;可选&#xff0c;用于开发时热部署&#xff09; 项目结构 src/main/j…

作者头像 李华
网站建设 2026/6/29 17:19:35

铝箔与铝制品自动检测:基于YOLO13-C3k2-ConvFormer的智能分类系统详解

1. 铝箔与铝制品自动检测&#xff1a;基于YOLO13-C3k2-ConvFormer的智能分类系统详解 1.1. 系统概述 铝制品在现代工业中应用广泛&#xff0c;从包装材料到电子元件&#xff0c;从建筑材料到航空航天部件&#xff0c;都离不开铝及其合金制品。然而&#xff0c;铝制品在生产过…

作者头像 李华
网站建设 2026/6/29 18:07:56

【稀缺技术公开】:R实现量子模拟飞秒级时间分辨率的秘密路径

第一章&#xff1a;R 量子模拟的测量精度在量子计算与量子模拟的研究中&#xff0c;测量精度是决定实验结果可信度的关键因素。R语言凭借其强大的统计分析能力与可视化工具&#xff0c;被广泛应用于量子模拟数据的后处理与误差分析中。通过精确建模测量噪声、系统漂移和量子态坍…

作者头像 李华
网站建设 2026/6/29 11:25:18

【临床数据R语言亚组分析实战】:掌握高效亚组挖掘技巧与代码实现

第一章&#xff1a;临床数据亚组分析概述 在临床研究中&#xff0c;亚组分析是一种重要的统计方法&#xff0c;用于探索治疗效应在不同患者群体中的异质性。通过对特定人口学特征、疾病严重程度或生物标志物等变量进行分层&#xff0c;研究人员能够识别出对干预措施反应更显著的…

作者头像 李华
网站建设 2026/6/30 7:54:14

为什么90%的AI语音项目都卡在音频质检?Dify 1.7.0给出答案

第一章&#xff1a;为什么90%的AI语音项目都卡在音频质检&#xff1f;在AI语音系统开发中&#xff0c;模型训练只是冰山一角&#xff0c;真正决定项目成败的是隐藏在背后的音频质检环节。大量团队在数据采集后直接进入训练阶段&#xff0c;却忽视了原始音频中存在的噪声、静音段…

作者头像 李华