反转链表系列问题总结(多种解法多种题型)

小黄鸭机器人技术全解-第 07 章 关节自由度与行程参数 —鸭子歪着头转头时,转的平面是斜的,这正是它"灵动"感的来源。仿真里这是自动的(轴定义在父刚体系),复刻时不需要做任何事—— 阅读详情

简介

反转链表是面试中常考问题,题型变化就那几种,包括整个链表的反转、范围反转等,本篇文章将这些问题放在一起进行讨论和总结,并对多种解法进行分析和对比,做到“一网打尽”!

反转链表系列题目

以上题目均来自leetcode

例题详细

1、反转链表

题目描述

反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

分析

虽然是一道简单题目,但是解法有很多种,还是有很多值得探讨的地方。

  • 方法一:借用列表法

将链表的节点放在一个列表中,利用列表进行反转,最后将反转后的节点组成新的链表。

这种解法操作起来简单,因为我们熟悉的是列表的反转,而对于链表的反转有点无从下手。

时间复杂度:将节点放入列表O(n),反转列表O(n),组成新的链表O(n),所以是O(3n)≈O(n)。

空间复杂度:需要用到一个列表存储链表节点,O(n)。

这种解法时间空间都没有什么优势,因此放弃。

  • 方法二:递归法

有链表:L1 -> L2 -> L3 -> L4,假如此时我们完成了L2到L4的反转,那么链表就是这样的:L4 -> L3 -> L2,同时L1 -> L2,此时我们需要将L1节点移动到L2之后,假设:
p: L4
head: L1
所以
head.next.next = head;
head.next = null;
描述半天可能说不清,直接看代码可能就能理解了。正所谓:talk is cheap, show me the code!

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode p = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return p;
    }
}

时间复杂度:需要对每个节点进行递归,因此时间复杂度为O(n)

空间复杂度:递归需要用到栈空间,每次的递归会在栈中压入一个栈帧,最大递归深度为O(n),但是相较于方法一中使用O(n)的堆空间,栈空间会伴随着递归结束而销毁,但是堆空间需要垃圾回收,所以栈空间稍稍有一点优势。

代码看起来清洁干净,且可读性强。

  • 方法三 修改指针法

创建一个dummy节点,指向head,从前往后遍历节点,将next指针指向前一个节点。

例如:

Ld -> L1 -> L2 -> L3 -> L4
Ld <- L1 -> L2 -> L3 -> L4
Ld <- L1 <- L2 -> L3 -> L4
Ld <- L1 <- L2 <- L3 -> L4
Ld <- L1 <- L2 <- L3 <- L4
null <- L1 <- L2 <- L3 -> L4

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode dummy = new ListNode(-1), next, pre = dummy, cur = head;
        dummy.next = head;
        while (cur != null) {
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        head.next = null;
        return pre;
    }
}

这种方法理解起来比较容易,最后注意把head的next指针指向null,因为反转之后head就是尾节点了。

时间复杂度:O(n)

空间复杂度:O(1)

  • 方法四 移动节点法

这种方法每次移动一个节点,从而达到反转的目的。

例如:

Ld -> L1 -> L2 -> L3 -> L4
Ld -> L2 -> L1 -> L3 -> L4
Ld -> L3 -> L2 -> L1 -> L4
Ld -> L4 -> L3 -> L2 -> L1

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode pre = new ListNode(-1), cur = head, next;
        pre.next = head;
        while (cur != null && cur.next != null) {
            next = cur.next;
            cur.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }
        return pre.next;
    }
}

这种方法是接下来几种题型的基础。

时间复杂度:O(n)

空间复杂度:O(1)

2、反转链表 II

题目描述

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例

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

分析

借用第1题的方法四,先找到第left个节点,然后再移动(right - left)次。

class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        if (left >= right) {
            return head;
        }
        ListNode dummy = new ListNode(-1), pre = dummy;
        dummy.next = head;
        ListNode cur = head, next;
        for (int i = 1; i < left; i++) {
            pre = pre.next;
            head = head.next;
        }
        for (int i = 0; i < right - left; i++) {
            next = head.next;
            head.next = next.next;
            next.next = pre.next;
            pre.next = next;
        }
        return dummy.next;
    }
}

时间复杂度:O(n)

空间复杂度:O(1)

3、K 个一组翻转链表

题目描述

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

k 是一个正整数,它的值小于或等于链表的长度。

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

进阶:

你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例

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

分析

每k个节点反转一次,不足k个时直接返回。

public class Solution {

    private ListNode[] reverse(ListNode head, ListNode tail) {
        ListNode dummy = new ListNode(-1), next;
        dummy.next = head;
        while (dummy.next != tail) {
            next = head.next;
            head.next = next.next;
            next.next = dummy.next;
            dummy.next = next;
        }
        return new ListNode[]{tail, head};
    }

    private ListNode[] reverse1(ListNode head, ListNode tail) {
        ListNode pre = new ListNode(-1), next, tailNext = tail.next;
        pre.next = head;
        while (head != tailNext) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        head.next = null;
        return new ListNode[]{tail, head};
    }

    public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode dummy = new ListNode(-1), pre = dummy, tail, nxt;
        dummy.next = head;

        while (head != null) {
            tail = pre;
            for (int i = 0; i < k; i++) {
                tail = tail.next;
                if (tail == null) {
                    return dummy.next;
                }
            }
            nxt = tail.next;
            ListNode[] nodes = reverse1(head, tail);
            pre.next = nodes[0];
            nodes[1].next = nxt;
            pre = nodes[1];
            head = nxt;
        }
        return dummy.next;
    }

其中 reverse 方法是移动节点法,reverse1 方法修改指针法。

时间复杂度:O(n)

空间复杂度:O(1)

Python爬虫实战:绕过Cloudflare反爬的最新技术与完整代码详解 在互联网数据采集领域,越来越多的网站开始部署CDN和安全防护服务,其中 Cloudflare 是最为广泛使用的防护方案之一。它不仅为网站提供DDoS防护,还能通过JS挑战、验证码和行为分析来识别并拦截爬虫。这给爬虫工程师带来了极大挑战——如何在不违反网站服务条款的情况下,实现有效的数据采集?本文将分享Python领域绕过Cloudflare反爬的最新技术方法,结合最新流行库与自动化浏览器,帮助你攻克这一难题。绕过Cloudflare反爬不是一蹴而就,需结合多技术、多策略,持续迭代。 阅读详情

相关推荐

链式中介效应结果解读:从Bootstrap置信区间到实践意义

本文深入解析链式中介效应结果的解读方法,从Bootstrap置信区间的应用到实践意义的阐述。通过实际案例展示如何分析总效应、直接效应和间接效应,并强调效应量评估的重要性。文章还提供了构建逻辑解释的三步法,以及敏感性分析和报告撰写的实用技巧,帮助研究者准确解读链式中介效应。

weixin_33690367的博客 718

【力扣精选】3分钟拿下反转链表所有题型

用画图的方式带你轻松解决面试高频题 -- 反转链表

秋刀鱼与猫的博客 3181

FANUC机器人KAREL编程实战:手把手教你用SOCKET指令连接外部设备(附完整.KL文件)

本文详细解析了FANUC机器人KAREL编程中SOCKET指令的应用,从开发环境配置到工业级通讯全流程,涵盖网络参数设置、模块化代码设计、错误处理及现场调试技巧。通过实战案例,帮助开发者掌握与外部设备稳定连接的关键技术,提升工业自动化系统的通讯可靠性。

weixin_30907935的博客 225

【数据结构】单链表的反转(难:腾讯面试题)

实现单链表的反转 真的是要被这题搞死了,这个问题看了几个小时,刚开始怎么都理解不了,还是很有难度的题目 整体分析: 代码实现: //方法:将单链表进行反转 public static void reverseList(HeroNode head){ //如果当亲链表为空或者只有一个节点,直接返回 if(head.next==null ||head.next.next==null...

JH灰色的博客 442

短视频mssdk中get_token协议逆向与加密流程深度解析

本文深度解析了短视频mssdk中get_token协议的逆向分析与加密流程。通过抓包、Frida Hook、静态分析等手段,详细拆解了协议数据的Protobuf结构、设备信息采集来源,并重点剖析了其核心加密链路:zlib压缩、自定义TEA算法与AES-CBC加密,最终实现完整的协议模拟。

flower的专栏 555

MindIE与vLLM-Ascend性能对决:Qwen3在昇腾910B上的推理效率实测

本文深度对比了昇腾910B平台上两大推理框架MindIE与vLLM-Ascend的性能表现。通过实测Qwen3系列模型,详细分析了二者在单卡、多卡场景下的推理效率、扩展性及生产环境适用性,为AI算力基础设施选型提供关键参考。

weixin_29214335的博客 1180

25. K 个一组翻转链表 (局部反转)

LeetCode: 25. K 个一组翻转链表 常数额外空间,反转链表 >> 用指针原地反转 有一说一, 这道链表题 >> 还挺难的。 注意点; 创建头节点 >> hair 理清思路 AC Code /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode()

lankerens 368

Vivado FIR Complier_IP核使用方法

文章依靠该IP核对应手册PG149写的,因为笔者需求简单,没有深入挖掘功能,可以自行下载学习。

2302_80180551的博客 3985

反转链表,每 k 个节点反转一次,不足 k 就保持原有顺序

// 反转链表,每 k 个节点反转一次,不足 k 就保持原有顺序 // 构建链表 function list(...val) { let obj = val.reverse().map((res, i) => Object.assign({}, { [i]: new Node(res) })); for (let item in obj) { if (item...

qq_40146880的博客 445

Pytest教程:Pytest插件原理

Pytest的插件系统是其强大功能的核心,它允许用户和开发者扩展和定制测试框架的行为。要深入理解Pytest插件的原理,我们需要从Pytest的架构和设计模式开始,然后深入到底层源码。

旦莫的博客 636

人形机器人硬件电路设计入门

人形机器人属于。

blotemj.blog.youkuaiyun.com 229

第 138 题:反转链表,每 k 个节点反转一次,不足 k 就保持原有顺序 [哔哩哔哩]

大致思路: 遍历链表,将每个元素添加到一个栈中 判断栈的长度,达到指定长度后,出栈,即可反转 若最后一次栈的长度没有达到指定长度,则将这个栈当作队列操作,直接出队 class Node { constructor(value) { this.value = value; this.next = null; } print() { let pointer...

包磊磊的博客 714

[QMT量化交易小白入门]-八十九、深度学习训练多维特征进行金融价格行情预测

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 218

LeetCode反转链表java_Leetcode 反转链表系列 图解详细过程

对于一个程序猿来说,数据结构和算法的重要性就不用我多说了吧,算法题已然成了现在大厂笔试面试的重头戏,废话少说,Leetcode 刷起来呀。说起刷 Leetcode,我建议你按 tag 刷,不然只能像无头苍蝇,东一榔头西一棒槌,最后事倍功半 (过来人的惨痛经历)。最近正好在刷 Leetcode 上的链表题,也碰到了一些颇具代表性的题型,正好做个记录,也分享给有需要的小伙伴。对链表不太熟悉的小伙伴碰到...

weixin_33444829的博客 580

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Leetcode 反转链表系列 图解详细过程

对于一个程序猿来说,数据结构和算法的重要性就不用我多说了吧,算法题已然成了现在大厂笔试面试的重头戏,废话少说,Leetcode 刷起来呀。说起刷 Leetcode,我建议你按 tag 刷,不然只能像无头苍蝇,东一榔头西一棒槌,最后事倍功半 (过来人的惨痛经历)。最近正好在刷 Leetcode 上的链表题,也碰到了一些颇具代表性的题型,正好做个记录,也分享给有需要的小伙伴。 对链表不太熟悉的小伙伴碰...

IamHYN的博客 624

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

链表OJ题核心解析与高频题型实战指南

链表作为基础数据结构,通过指针操作实现动态内存管理,在算法面试和系统设计中具有重要地位。其核心原理涉及节点遍历、指针修改和内存管理三个维度,典型应用场景包括LRU缓存、任务调度等系统设计。技术价值体现在训练编程思维、优化内存使用和提升算法效率上。本文以LeetCode高频题型为例,深入解析移除链表元素、链表分割等问题的双指针解法,结合哨兵节点技巧和边界条件处理,帮助开发者掌握链表OJ题的解题范式与工程实践要点。

weixin_31412781的博客 4

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

算法基础之链表相关实战(Leetcode题型归纳)

算法基础之链表相关实战(Leetcode题型归纳)1.常用技巧2.链表基本操作类题目2.1介绍2.2真题分析2.2.1移除链表元素(203)2.2.2删除链表中的节点(237)2.2.3分隔链表(86)2.2.4两两交换链表中的节点(24)2.2.5旋转链表(61)2.2.6重排链表(143)3.反转类题目3.1介绍3.2真题分析3.2.1反转链表(206)3.2.2反转链表2(92)3.2.3 k个一组翻转链表(25)4.双指针问题4.1介绍4.2真题分析4.2.1删除链表的倒数第N个节点(19)4.2.

Buluchacha的博客 235

【每日易题】数据结构链表篇——单链表oj题(1),几道典型例题带你快速掌握单链表

精选leetcode与牛客网典型oj例题,带你深入单链表的实际应用!!!

君兮_的博客 845

力扣链表题核心套路:高频题型与边界处理技巧

链表是一种基础且应用广泛的数据结构,其操作核心在于对节点指针的精准控制。理解遍历与指针重接两大基本动作,是掌握各类链表算法的前提。在工程实践中,链表常用于实现缓存、内存管理等场景,而技术面试中,链表题也是考察候选人基本功的高频题型。围绕力扣中的高频题目,虚拟头节点能够简化边界处理,快慢指针可以解决中点、环检测及倒数节点等经典问题,反转与合并则考验递归与迭代的综合运用。掌握这些核心套路,不仅能提高刷题效率,也能在面试中快速构建清晰的解题思路。文章从实际刷题经验出发,系统拆解链表题型的解题模板与易错边界,帮助开

weixin_33326218的博客 214

链表操作:反转与回文判断的算法解析

链表是数据结构中的基础类型,通过指针连接实现非连续存储,兼具插入删除高效性和随机访问局限性。其核心操作涉及指针控制与节点关系维护,在算法面试中具有极高出现频率。反转链表作为指针操作的经典案例,考察对链表结构的深入理解;而回文链表判断则结合了快慢指针与反转技巧,展现了算法优化的典型思路。这两种操作不仅常见于技术面试,也是解决复杂链表问题的基础,如K个一组反转、指定区间反转等变种题目。通过迭代法和递归法的对比实现,可以深入理解时间空间复杂度的权衡,而快慢指针法则体现了降低空间复杂度的优化策略。掌握这些基础操作,

weixin_30984001的博客 13

LeetCode链表算法精解:高频题型与核心技巧

链表作为基础数据结构,通过指针实现非连续存储,其核心价值在于高效的动态内存管理。在算法领域,链表操作常考察指针控制能力,典型如反转链表、环形检测等高频题型。理解快慢指针、虚拟头节点等技巧,能有效解决LeetCode中15%的链表问题。工程实践中,这些技术广泛应用于LRU缓存实现、大数运算等场景。本文以反转链表和环形检测为例,结合代码示例解析指针操作的精髓,帮助开发者掌握链表算法的核心思维模式。

weixin_33806859的博客 5

链表面试核心技巧全解读:从反转链表到快慢指针的实战指南

链表作为数据结构领域的基础线性结构,是算法面试中考察指针操作与边界思维的经典载体。无论是反转链表的迭代与递归实现,还是合并有序链表时虚拟头节点的巧妙运用,都体现了对引用与内存管理的深刻理解。快慢指针在环形链表、链表中点及回文判断等场景中的统一解法,更成为解决复杂链表问题的核心范式。这些技术不仅是应对大厂面试的必备技能,也为理解缓存淘汰、内存管理等工程实践提供了底层逻辑。本文围绕牛客101中的高频链表题型,从实战角度拆解六类典型问题,涵盖代码模板、复杂度分析与面试表达技巧,帮助开发者系统构建链表解题模式,在算

weixin_34116482的博客 277

LeetCode算法之--链表系列

LeetCode链表常见算法题型

程序大视界 1225

链表算法精解:LeetCode高频题型与工程实践

链表作为基础数据结构,通过节点指针实现动态存储,在插入删除操作上具有O(1)时间复杂度优势。其核心原理在于指针操作与节点关系维护,这种特性使其成为算法面试的高频考点(出现率达35%)。从技术实现看,双指针技巧与哨兵节点模式能解决90%的链表问题,如反转链表、环检测等经典题型。在工程实践中,链表广泛应用于内存管理、LRU缓存等场景,但需注意多线程安全与内存泄漏问题。通过系统掌握归并排序等算法优化策略,开发者能提升对复杂链表问题的拆解能力,这也是衡量程序员基本功的重要标准。

weixin_33508411的博客 234

链表核心能力:快慢指针与原地反转攻克回文和相交问题

链表是一种基础的数据结构,节点通过next指针单向连接,不能像数组那样随机访问或回溯。判断回文链表和查找相交链表,正是对链表底层掌控力的经典考察。快慢指针用于定位中点,原地反转用于调整后半段方向,双指针则能消除两条链表的路程差。这些核心技巧不仅服务于LeetCode刷题与算法面试,也广泛用于环形链表检测、LRU缓存等工程实现。理解指针操作的边界条件,掌握从数组思维到链表思维的转换,能够帮助开发者在内存受限的场景下设计出O(1)额外空间的算法。回文判断的关键在于对称比较,相交查找的关键在于节点地址身份的识别。

weixin_31766003的博客 271

链表算法精讲:Hot100高频题型与解题技巧

链表是数据结构中的基础概念,通过节点和指针实现动态存储。其核心原理在于指针操作,包括节点的插入、删除和遍历。在算法领域,链表问题常考察指针操作技巧和边界条件处理,具有重要的技术价值。常见的应用场景包括环形链表检测、分组反转链表等,这些题目在LeetCode Hot100中频繁出现。掌握虚拟头节点、快慢指针等技巧,能有效解决链表III类中高难度问题。本文以反转链表II和K个一组反转链表为例,详解链表问题的通用解法套路和边界条件处理要点,帮助开发者提升算法能力。

weixin_32715349的博客 170
上一篇: 算法之单调栈的使用总结(含接雨水、柱状图等经典问题)
下一篇: 算法之N数之和
Elmerr
博客等级 码龄12年 178粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值