当前位置: 首页 > article >正文

【反转链表系列】力扣206,92,25

文章目录

  • 一、前言
  • 二、反转链表
  • 三、反转链表 II
  • 四、K 个一组翻转链表

一、前言

本文涉及的力扣题目,涉及简单、中等、困难三个难度

  1. 力扣206.反转链表
  2. 力扣92.反转链表 II
  3. 力扣25.K 个一组翻转链表

反转链表这类型的题目,折磨了挺久,经常弄懂了一道题,但是遇到下一道反转链表的题目还是不会。

所以我整理了三道比较经典的反转链表的题目,从浅到深一步一步领悟反转链表的处理思路。


二、反转链表

力扣206.反转链表

这是一道力扣上的简单难度的反转链表的题目,要求我们将给定的链表进行反转。

image-20241226213533846

这道题解题思路也非常简单,就是将指针反转即可,思路虽然简单,但是编写代码的时候却很容易乱。

我们思考一个问题,反转一个链表,肯定是每两个节点之间的指针先进行反转,然后遍历下来就可以了。

那么需要多少个节点指针呢?是的,需要三个!

  1. pre:表示前一个结点
  2. cur:表示当前节点
  3. next:表示下一个节点

为什么需要next指针呢?

答:是因为当precur之间的指针反转后,如果没有next指针记录cur的下一个节点,反转后就无法找到cur的下一个节点

如下图所示,第一次反转之前先记录cur的下一个节点

image-20241226214645404

那么循环中第一次反转,cur的下一个节点指向pre

image-20241226215126779

反转后,cur所指向的节点就是下一次反转的prenext指针所指向的节点,就是下一次的当前节点,next也要进行更新。

于是第一次反转后链表变成下图所示

image-20241226215724112

同理,进行第二次反转

image-20241226215806953

第三次反转

image-20241226215837196

第四次反转

image-20241226215913479

第五次反转

image-20241226215949016

curnull的时候,说明链表已经反转完成,此刻pre就是链表的头部!

要非常熟悉这个反转整个链表的流程,因为后面两道题反转链表的流程和这道题差不多,只是不是处理一整条链表而已!

记住这个结论:当链表反转完成后,pre就是链表的头部。

后面会是使用到这个结论

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode pre = null;
        ListNode next = null;
        while(cur != null){
            next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return pre;
    }
}
  • 时间复杂度:O(n),n为链表长度
  • 空间复杂度:O(1)

相信看到这里,你已经完全掌握了链表反转的方法,后面会一直沿用这个思路去解决问题!


三、反转链表 II

力扣92.反转链表 II

反转链表 II和上一题的区别就是不是反转一整个链表,而是反转从位置 left 到位置 right 的链表节点

那么我们就必须先找到位置位于left - 1上的节点p0,然后对[left,right]位置上的链表节点进行反转即可,反转的步骤和上面的反转链表的思路一样,然后再把反转后的链表连接起来即可!

为什么要找位于left - 1上的节点?

答:因为题目要求反转[left,right]上的节点,那么原链表就被划分成了三部分,分别是原左链表、需要反转的链表、原右链表。找到位于left - 1位置上的节点是为了记录原左链表的最后一个节点的指针,方便反转后链接链表使用

反转[left,right]位置上之后,就会如下图所示,这时候需要将p0.next.next指向curp0.next指向pre,这样就完成了链表的部分反转。

image-20241228105017027

这里需要注意,假如链表的长度是1的话,那么就不会存在就不会有位于left - 1上的节点,于是我们需要定义一个哨兵节点,用作指向这个链表的头节点

class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        head = new ListNode(-1, head);
        ListNode cur = head;
        ListNode pre = null;
        for(int i = 0; i < left - 1 ; i ++){
            cur = cur.next;
        }
        ListNode p0 = cur;
        cur = cur.next;
        for(int i = left; i <= right; i ++){
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;        
        }
        p0.next.next = cur;
        p0.next = pre;
        return head.next;
    }
}	
  • 时间复杂度:O(n),n为链表长度
  • 空间复杂度:O(1)

四、K 个一组翻转链表

力扣25.K 个一组翻转链表

这道题结合了上面两道题,需要对链表每K个为一组,进行翻转。

既然是分组,那么我们就需要先计算链表的长度,然后看看链表能分成多少组,记录一个组数。

然后根据反转链表 II的做法,进行一组一组反转即可,每次反转完一组后,需要更新p0的所在位置

image-20241228105944269

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        // 计算链表的长度
        int count = 0;
        ListNode cur = head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        // 处理的次数
        int n = count / k;
        head = new ListNode(-1, head);
        ListNode p0 = head;
        ListNode pre = null;
        ListNode next = null;
        cur = head.next;
        while (n-- > 0) {
            for (int i = 0; i < k; i++) {
                next = cur.next;
                cur.next = pre;
                pre = cur;
                cur = next;
            }
            ListNode nxt = p0.next;
            p0.next.next = next;
            p0.next = pre;
            p0 = nxt;
        }
        return head.next;
    }
}	


http://www.kler.cn/a/456195.html

相关文章:

  • 华诺星空 Java 开发工程师笔试题 - 解析
  • 浏览器http缓存问题
  • 大语言模型(LLM)中大数据的压缩存储及其重要性
  • 【Unity3D】ECS入门学习(七)缓存区组件 IBufferElementData
  • oracle基础:中文字段排序详解
  • 只谈C++11新特性 - 删除函数
  • WINDOWS对话框模板结构简析
  • 接口自动化测试平台项目环境搭建
  • 如何使用Porcupine做一个安卓端语音唤醒demo
  • java相关学习文档或网站整理
  • 【MySQL】数据库初始化报错
  • Mono里运行C#脚本7—MonoImageStorage结构解析
  • 【Sentinel】初识Sentinel
  • 【小程序】全局配置window和tabBar
  • 在 Windows 11 下的 WSL - Ubuntu 24.04 中安装 Anaconda3
  • jmeter混合场景测试,设置多业务并发比例(吞吐量控制器)
  • 【AI日记】24.12.28 kaggle 比赛 2-16
  • uniapp实现APP、小程序与webview页面间通讯
  • IPv6 基础协议-NDP
  • Jupyter在运行上出现错误:ModuleNotFoundError: No module named ‘wordcloud‘
  • Java全栈项目实战:校园报修服务系统
  • STM32F103RCT6学习之五:ADC
  • Element Plus 日期时间选择器大于当天时间置灰
  • QT应用单例——qtsingleapplication
  • 设计模式之模板方法模式:咖啡,茶,和代码
  • 经典问题——华测