LeetCode 第25题:K 个一组翻转链表

news/2025/2/15 1:07:28/文章来源:https://www.cnblogs.com/lavender-vv/p/18716428

LeetCode 第25题:K 个一组翻转链表

题目描述

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

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

难度

困难

题目链接

https://leetcode.cn/problems/reverse-nodes-in-k-group/

示例

示例 1:

K个一组翻转链表

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

示例 2:

K个一组翻转链表

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

提示

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

解题思路

方法一:迭代法

使用迭代的方式,每次处理k个节点。

关键点:

  1. 使用虚拟头节点简化操作
  2. 每次翻转前先判断剩余节点数量是否足够
  3. 保存每组k个节点的前驱和后继
  4. 翻转k个节点后重新连接

具体步骤:

  1. 创建虚拟头节点
  2. 计算链表长度
  3. 对于每组k个节点:
    • 判断剩余节点是否足够k个
    • 保存组的前驱和后继
    • 翻转k个节点
    • 连接翻转后的组
  4. 返回虚拟头节点的下一个节点

时间复杂度:O(n),其中n是链表的长度
空间复杂度:O(1)

方法二:递归法

利用递归的特性,将问题分解为子问题。

递归思路:

  1. 基线条件:剩余节点不足k个
  2. 对于每组k个节点:
    • 翻转当前k个节点
    • 递归处理后续节点
  3. 返回新的头节点

代码实现

C# 实现(迭代法)

/*** Definition for singly-linked list.* public class ListNode {*     public int val;*     public ListNode next;*     public ListNode(int val=0, ListNode next=null) {*         this.val = val;*         this.next = next;*     }* }*/
public class Solution {public ListNode ReverseKGroup(ListNode head, int k) {if (head == null || k == 1) return head;// 创建虚拟头节点ListNode dummy = new ListNode(0);dummy.next = head;ListNode prev = dummy;ListNode curr = head;// 计算链表长度int length = 0;while (head != null) {length++;head = head.next;}// 处理每组k个节点for (int i = 0; i < length / k; i++) {// 翻转k个节点for (int j = 1; j < k; j++) {ListNode next = curr.next;curr.next = next.next;next.next = prev.next;prev.next = next;}prev = curr;curr = curr.next;}return dummy.next;}
}

C# 实现(递归法)

public class Solution {public ListNode ReverseKGroup(ListNode head, int k) {if (head == null || k == 1) return head;// 检查剩余节点是否足够k个ListNode curr = head;int count = 0;while (curr != null && count < k) {curr = curr.next;count++;}// 如果不足k个节点,返回原链表if (count < k) return head;// 翻转k个节点curr = head;ListNode prev = null;ListNode next = null;for (int i = 0; i < k; i++) {next = curr.next;curr.next = prev;prev = curr;curr = next;}// 递归处理后续节点head.next = ReverseKGroup(curr, k);return prev;}
}

代码详解

迭代版本:

  1. 初始化:
    • 使用dummy节点简化操作
    • 计算链表总长度
  2. 翻转过程:
    • 每次处理k个节点
    • 保持组内节点的连接关系
    • 更新前驱和后继指针
  3. 边界处理:
    • 判断剩余节点数量
    • 处理不足k个节点的情况

递归版本:

  1. 基线条件:
    • 检查剩余节点数量
    • 处理不足k个的情况
  2. 递归过程:
    • 翻转当前k个节点
    • 递归处理后续节点
    • 连接翻转后的部分

执行结果

迭代版本:

  • 执行用时:92 ms
  • 内存消耗:38.2 MB

递归版本:

  • 执行用时:88 ms
  • 内存消耗:38.4 MB

总结与反思

  1. 这是一道高难度的链表操作题目:
    • 考察链表的基本操作
    • 考察分组处理的思想
    • 考察边界情况的处理
  2. 两种解法比较:
    • 迭代:空间效率好,实现较复杂
    • 递归:代码简洁,但空间开销大
  3. 优化思路:
    • 预先计算长度避免重复遍历
    • 使用虚拟头节点简化操作
    • 仔细处理边界情况

相关题目

  • LeetCode 第24题:两两交换链表中的节点
  • LeetCode 第206题:反转链表
  • LeetCode 第92题:反转链表 II
  • LeetCode 第61题:旋转链表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/884005.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HJ25 数据分类处理

题目:我的答案: #include <iostream> #include <string> #include <vector> #include <set> #include <map>using namespace std;bool match(const int R, const string &I) {if (I.find(to_string(R)) != std::string::npos){return true;}…

Java Web - 后端

Java Web 后端的基础知识: Maven, Spring Boot, MySQL, JDBC, MyBatisJava Web - 后端 Maven 基于项目对象模型 (POM) 的概念, 通过一小段描述信息来管理项目的构建 官网各种插件以构建生命周期/阶段依赖管理模型从仓库中查找 jar包仓库: 存储资源, 管理 jar包本地仓库: 自己计…

汇编语言笔记_1

汇编语言学习笔记(一)1.基础知识 汇编语言是直接在硬件上工作的语言,本章重在了解硬件系统结构 1.1 机器语言 CPU(中央处理单元)是一种微处理器,功能是执行机器指令每一种微处理器由于硬件设计和内部结构的不同,有自己的机器指令集,也就是机器语言由于机器码晦涩难懂和…

基于FPGA的图像双线性插值算法verilog实现,包括tb测试文件和MATLAB辅助验证

1.算法运行效果图预览 (完整程序运行后无水印)这里实现的是256*256双线性插值到512*512的系统模块局部放大:将数据导入到matlab,得到插值效果图:2.算法运行软件版本 matlab2022avivado2019.23.部分核心程序 (完整版代码包含详细中文注释和操作步骤视频)`timescale 1ns / 1…

Windows Teminal 自定义标题

背景与痛点场景: 开发环境,用命令行开了好几个微服务,窗口标题都是一样的,不好分清哪个窗口是哪个服务的了。所有窗口默认显示相同的标题(如"C:\Windows\System32\cmd.exe dotnet run")。窗口多了,切换也不方便。 解决方案: 使用Windows Teminal 来运行命令启…

前端开发day2

前端开发day2 今日概要:案例应用(利用之前所学知识) CSS知识点 模板 + CSS + 构建页面1.CSS案例 1.1 内容回顾HTML标签 固定格式,记住标签长什么样子,例如: h/div/span/a/img/ul/li/table/input/formCSS样式引用CSS:标签、头部、文件 .xx{... }<div class=xx xx>&…

基于电导增量MPPT控制算法的光伏发电系统simulink建模与仿真

1.课题概述 基于电导增量MPPT控制算法的光伏发电系统simulink建模与仿真。输出MPPT跟踪后的系统电流,电压以及功率。2.系统仿真结果3.核心程序与模型 版本:MATLAB2022a4.系统原理简介电导增量调制(Incremental Conductance, IC)算法是光伏发电系统中广泛应用的…

可持久化权值线段树(主席树)笔记

可持久化权值线段树(主席树)笔记 区别于普通线段树,权值线段树维护的信息不同普通线段树:节点区间是序列的下标区间,维护区间最值,区间和等信息 权值线段树:节点区间是序列的值域,维护值域内数出现的次数*图片引自董晓算法给定一个区间,询问该区间内的第 \(k\) 小值是…

基于排队理论的客户结账等待时间MATLAB模拟仿真

1.程序功能描述 基于排队理论的客户结账等待时间MATLAB模拟仿真,分析平均队长,平均等待时长,不能结账的概率,损失顾客数,到达顾客数,服务顾客数,平均服务时间。 2.测试软件版本以及运行结果展示MATLAB2022A版本运行 3.核心程序figure; plot(mean(mLen_seq,2),-b^…

【牛客训练记录】牛客2025年情人节比赛

训练情况赛后反思 今年比赛比去年有意思多了,太搞笑了 A题 我们构造一对就可以了,和为 \(x\),直接扔上去 \(1\) 和 \(x-1\) 即可点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;void solve(){int x; cin>>…

PVE8.3.1 直通硬盘

直通可以分为全盘直通和硬件直通,硬件直通会将整个 SATA 控制器直通给虚拟机,这可能会导致所有硬盘都分配给了一个虚拟机,这里介绍全盘直通。 1,查看硬盘IDls /dev/disk/by-id如上图ata 开头的设备就表示 sata 硬盘2,硬盘直通qm set 虚拟机id -sata0 /dev/disk/by-id/ata…