LeetCode链表题?来让我帮你图解剖析

news2024/12/23 10:50:02

💐文章导读

本篇文章主要详细的用图解的方式为大家讲解了简单程度的链表题,如果题中有错误的地方,还麻烦您在评论区指出,你的意见就是我最大的进步!!!

💐专栏导读

🤴作者:🦁努力努力再努力

🏆文章专栏:🌷《JavaSE语法》 、 🌷《C语言初阶》、 🌷《图解LeetCode》、 🌺《数据结构剖析》

文章目录

  • 💐文章导读
  • 💐专栏导读
  • 1、环形链表
  • 2.环形链表进阶版
  • 3.相交链表
  • 4.删除排序链表中的重复元素
  • 5.移除重复节点
  • 6.删除中间节点
  • 7.二进制链表转整数
  • 9.翻转链表
  • 10.链表中倒数第K个结点
  • 11.从头到尾打印链表

1、环形链表

思路:本体主要是利用双指针进行解题,分别定义一个快指针和慢指针,快指针一次走两步,慢指针一次走一步,如果链表有环的情况下,快慢指针直接差的距离最多是一个环的距离,肯定不会超过一个环,所以就需要用一个循环让快慢指针分别走,当两个指针相遇时,就返回true,就表明链表有环,如果循环结束了还没有返回,就表明链表没环,而循环结束的条件就是fast==null || fast.next == null时,表明链表已经走完了。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.环形链表进阶版

在这里插入图片描述

在这里插入图片描述

    public ListNode detectCycle(ListNode head) {
        if(head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null && fast.next!=null) {//查找在环中相遇时的节点
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }
        }
        if( fast==null || fast.next==null) {
            return null;
        }
        fast = head;
        while(fast != slow){
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
    }

3.相交链表

在这里插入图片描述

思路:

如果要求两个链表的在什么地方相交,就要从两个链表的同一个节点向后遍历,所以首先要算出两个链表的长度差,让长的链表向后先走差值步,然后两个链表再一起向后走,直到遇见相同的地址处!

下面有图解:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
                //1、分别求2个链表的长度
            int lenA = 0;
            int lenB = 0;
            int len = 0;
            ListNode curA = headA;
            ListNode curB = headB;
            while(curA != null) {
                lenA++;
                curA = curA.next;
            }
            while(curB != null) {
                lenB++;
                curB = curB.next;
            }
            curA = headA;
            curB = headB;
            len = lenA-lenB;
            if(len<0) {
              curA = headB;
              curB = headA;
              len = lenB-lenA;
            }
            for(int i=0; i<len; i++) {
                curA = curA.next;
            }
            while(curA!= null && curB!=null) {
                if(curA == curB){
                    return curA;
                }
                 curA = curA.next;
                curB = curB.next;
            } 
            return null;
    }

在这里插入图片描述

在这里插入图片描述

4.删除排序链表中的重复元素

在这里插入图片描述

在这里插入图片描述

5.移除重复节点

在这里插入图片描述

双指针解法:
定义一个cur1指向头节点,再定义一个cur2指向cur1,用cur2区遍历所有的节点中val值与cur1中的val值作对比,如果相同就删除,否则就一直遍历

  public ListNode removeDuplicateNodes(ListNode head) {
        if(head == null) {
            return null;
        }
        ListNode cur1 = head;
        while(cur1 != null){
            ListNode cur2 = cur1;
            while(cur2.next != null){
                if(cur2.next.val == cur1.val) {
                    cur2.next = cur2.next.next;
                }else{
                    cur2 = cur2.next;
                }
            }
            cur1 = cur1.next;
        }
        return head;
    }

在这里插入图片描述

6.删除中间节点

在这里插入图片描述

解题思路:

要删除中间节点的话本来应该要找到中间节点的前驱的,但是现在只给了中间节点,那么可以这样做,可以把中间节点的后继节点中的val值赋给中间节点的val值,然后把后继节点删除掉,这样也符合题目要求

 public void deleteNode(ListNode node) {
        node.val = node.next.val;
        node.next = node.next.next;
    }

7.二进制链表转整数

在这里插入图片描述

   //第一种方法:利用按位或
public int getDecimalValue(ListNode head) {
        int ans = 0;
        ListNode cur = head;
        while(cur != null) {
            ans  = ans<<1;
            ans |= cur.val;
            cur = cur.next;
        }
        return ans;
    }
//第二种方法:利用换算二进制方法
       public int getDecimalValue(ListNode head){
           ListNode cur = head;
           int ans = 0;
           while(cur != null) {
               ans = ans*2+cur.val;
               cur = cur.next;
           }
           return ans;
       }

在这里插入图片描述

9.翻转链表

在这里插入图片描述

解题思路:

1、翻转链表就是将后面的每一个节点都存储前面一个节点的地址

2、因为链表都是从前向后走的,如果想要让后一个节点cur中的next变成前一个节点的地址,就需要知道前一个节点的地址;所以需要用一个变量prev来记录前一个结点,再用一个变量next来记录第三个结点,以方便中间的节点向后走,不然的话,当中间节点内的next改变以后,没办法找到第三个节点的位置,然后三个记录节点的变量分别向后走,这样知道前面一个节点和后面一个节点,就可以进行翻转!

   public ListNode reverseList(ListNode head) {
        if(head == null) {
            return null;
        }
        ListNode curprev = null;
        ListNode cur = head;
        while(cur != null) {
            ListNode next = cur.next;
            cur.next = curprev;
            curprev = cur;
            cur = next;
        }
        head = curprev;
        return head;
    }

10.链表中倒数第K个结点

在这里插入图片描述

解题思路:

1、求链表中倒数第K个结点,应该思考当给过k之后,应该怎么找这个倒数第k个节点,就拿题中给的事例来说,求倒数第二个结点就是4,可以用快慢指针的方法,而快慢指针的概念就是,假如有两个人A和B,它们都距离目的地差10步,如果让A先提前走三步,那么A和B之间就会差三步,然后让A和B在一人一步走,这样当A走到目的地时,B还是和A差三步远,而这个B正好在倒数第三个位置。路程不同,时间相同,速度相同,最后得到的就是路程差

所以此题定义一个fast快指针和slow慢指针,让快指针先走k步,当快指针走到空时,满指针正好在倒数第k的位置

 public ListNode getKthFromEnd(ListNode head, int k) {
        if(head == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        for(int i =0; i<k; i++) {
            fast =fast.next;
        }
        while(fast != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

11.从头到尾打印链表

在这里插入图片描述

解题方法:

1、先计算链表的长度,作为数组的长度

2、判断链表是否为空,为空则数组也为空,返回空数组

3、从数组的最后的下标开始放链表中的val

    public int[] reversePrint(ListNode head) {
        int len = 0;
        ListNode cur = head;
        //计算链表的长度
        while(cur!=null){
            len++;
            cur = cur.next;
        }
        int[] arr = new int[len];
        //如果链表为空则返回空数组
        if(head == null) {
            return arr;
        }
        因为数组下标是从0开始的所以减一
        int i =len-1;
        cur = head;
        while(cur!=null) {
            //从数组的最后开始放
            arr[i--] = cur.val;
            cur = cur.next;
        }
        return arr;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

免费用GPT4方法,速看可能会被删

介绍4种免费使用GPT4的方法&#xff0c;最后一个目前能多轮对话基本没限制。 1. forefront https://chat.forefront.ai/ 不登陆只能用GPT3.5&#xff0c;登陆后可以使用GPT4&#xff08;每3小时5条消息&#xff09; 2、poe https://poe.com/GPT-4 登陆后&#xff0c;每天…

【追梦之旅】—— 手“C”二叉树~

【追梦之旅】—— 手“C”二叉树~&#x1f60e; 前言&#x1f64c;什么是二叉树&#xff1f;&#xff01;特殊的二叉树二叉树的性质二叉树的存储结构二叉树链式结构的实现二叉树的链式结构&#xff1a;二叉树的创建。 二叉树的遍历前序遍历&#xff08;先根遍历&#xff09;中序…

java springboot yml文件配置 多环境yml

如果是properties改用yml&#xff0c;直接改后缀&#xff0c;原文件中的配置语法改用yml的语法即可&#xff0c;系统会自动扫描application.properties和application.yml文件&#xff08;注意&#xff1a;改了之后需要maven 命令 clean一下&#xff0c;清个缓存&#xff09;。 …

VSOMEIP3抓包数据

环境 $ cat /etc/os-release NAME"Ubuntu" VERSION"20.04.6 LTS (Focal Fossa)" IDubuntu ID_LIKEdebian PRETTY_NAME"Ubuntu 20.04.6 LTS" VERSION_ID"20.04" HOME_URL"https://www.ubuntu.com/" SUPPORT_URL"https:/…

简洁灵活工单管理系统,支持工单模版字段、工单状态自定义

一、开源项目简介 本项目为FeelDesk工单管理系统的开源版&#xff08;OS&#xff09;&#xff0c;是基于开发者版&#xff08;DEV&#xff09;分离的标准版&#xff1b;支持工单模版字段、工单状态等自定义&#xff0c;可为不同的模版设置不同的路由规则&#xff1b;对工单需求…

信号在MATLAB中的运算——信号的相加相乘

信号在MATLAB中的运算——信号的相加相乘 信号的相加和相乘是指同一时刻信号取值的相加和相乘。 对于离散序列来说&#xff0c;序列相加是将信号对应时间序列的值逐项相加&#xff0c;在这里不能像连续时间信号那样用符号运算来实现&#xff0c;而必须用向量表示的方法&#…

Python获取北上广深历史天气数据并做数据可视化

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 知识点: 动态数据抓包 requests发送请求 结构化非结构化数据解析 开发环境: 开发环境: python 3.8 运行代码 pycharm 2022.3.2 辅助敲代码 专业版 模块使用&#xff1a; requests 发送请求 pip install requests par…

2.2.2 部署Master节点、添加Node节点

2.2.2 部署Master节点 1.安装docker、kubeadm、kubelet、kubectl 前面我们已经完成了虚拟机中系统的初始化&#xff0c;下面我们就在我们所有的节点上安装docker、kubeadm、kubelet、kubectl。 Kubernetes默认CRI&#xff08;容器运行时&#xff09;为Docker&#xff0c;因此…

【JavaScript】拾遗(5.25)

文章目录 1. JavaScript2.HTML嵌入JS的第一种方式:行间事件3.HTML嵌入JS的第二种方式:脚本块的方式4. HTML嵌入JS的第三种方式:外部式(外链式)5. 局部变量和全局变量6. 函数7.事件8.回调函数8.1 注册事件8.2 代码的执行顺序 1. JavaScript JavaScript是一门脚本语言。&#xf…

微服务开发系列 第六篇:Redisson

总概 A、技术栈 开发语言&#xff1a;Java 1.8数据库&#xff1a;MySQL、Redis、MongoDB、Elasticsearch微服务框架&#xff1a;Spring Cloud Alibaba微服务网关&#xff1a;Spring Cloud Gateway服务注册和配置中心&#xff1a;Nacos分布式事务&#xff1a;Seata链路追踪框架…

动态规划-分割回文串 II

动态规划-分割回文串 II 1 题目描述2 示例2.1 示例 1&#xff1a;2.2 示例 2&#xff1a;2.3 示例 3&#xff1a;2.4 提示&#xff1a; 3 解题思路和方法3.1 解题思路3.1.1 确定状态3.1.2 转移方程3.1.3 初始条件和边界情况3.1.4 计算顺序3.1.5 回文串的判断方法 3.2 算法代码实…

day17 - 用形状包围图像

在进行图像轮廓提取时&#xff0c;有的情况下不需要我们提取出精确的轮廓&#xff0c;只要提取出一个接近于轮廓的近似多边形&#xff0c;就可以满足后续的操作。 本期我们来学习如何通过设置参数来找出图像的近似多边形。 完成本期内容&#xff0c;你可以&#xff1a; 了解…

《汇编语言》- 读书笔记 - 第5章- [BX]和 loop 指令

《汇编语言》- 读书笔记 - 第5章- [BX]和 loop 指令 5.1 [BX]问题 5.1 5.2 Loop 指令任务 1任务 2任务 3程序 5.1问题 5.2问题 5.2 5.3 在 Debug 中跟踪用 loop 指令实现的循环程序5.4 Debug 和汇编编译器 masm 对指令的不同处理DebugMASM 5.5 loop 和[bx]的联合应用程序 5.5问…

大数据项目实战之数据仓库:电商数据仓库系统——第9章 数仓开发之DWD层

文章目录 第9章 数仓开发之DWD层9.1 交易域加购事务事实表9.2 交易域下单事务事实表9.3 交易域取消订单事务事实表9.4 交易域支付成功事务事实表9.5 交易域退单事务事实表9.6 交易域退款成功事务事实表9.7 交易域购物车周期快照事实表9.8 工具域优惠券领取事务事实表9.9 工具域…

Python论文复现:VMD之自适应选择分解模态数K值

Python论文复现&#xff1a;《基于稀疏指标的优化变分模态分解方法》 信号分解方法中&#xff0c;虽然变分模态分解&#xff08;Variational Mode Decomposition, VMD&#xff09;有严格的数学推导&#xff0c;能有效抑制端点效应、模态混叠等问题&#xff0c;但其分解模态数需…

Docker笔记9 | Docker中网络功能知识梳理和了解

9 | Docker中网络功能知识梳理和了解 1 外部访问容器1.1 访问方式1.2 映射所有接口地址1.3 映射到指定地址的指定端口1.4 映射到指定地址的任意端口1.5 查看映射端口配置 2 容器互联2.1 新建网络2.2 连接容器 3 配置DNS 简单说&#xff1a;Docker 允许通过外部访问容器或容器互…

Python中的全局变量与局部变量

1 定义 全局变量指的是在整个python文件中定义的变量&#xff0c;而局部变量是在函数内部定义的变量。 a 1 def yang_func():b 2 从以上代码中可以看出&#xff0c;变量a是全局变量&#xff0c;变量b是定义在yang_func()函数的内部&#xff0c;因此b是局部变量。 2 使用范…

云原生之部署Docker管理面板SimpleDocker

云原生之部署Docker管理面板SimpleDocker 一、SimpleDocker介绍1. SimpleDocker简介2. SimpleDocker特点 二、本地环境介绍1. 本地环境规划2. 本次实践介绍 三、本地环境检查1.检查Docker服务状态2. 检查Docker版本3.检查docker compose 版本 四、下载SimpleDocker镜像五、部署…

【GD32开发】一、GD32F103 TIMER0 PWM死区时间计算

一、PWM死区时间如何计算&#xff1f; GD32F103的数据手册关于死区时间控制的公式如上图。 DTCFG的值为 设置死区结构体的寄存器值 tDTS_CK的值为 系统时钟的时钟周期。 如&#xff1a;GD32F103的系统时钟是108Mhz, 则tDTS_CK 1/108Mhz 9.26ns。( stm32的这个值跟定时器的…

如何从 Android 内部存储中恢复已删除的照片?

我们使用手机录制的照片和视频通常存储在手机的内存中。我们存储它们以记住我们生活的美丽。然而&#xff0c;在管理这些照片的过程中&#xff0c;一些用户却发现自己不小心删除了这些照片&#xff0c;这很尴尬。 如果您的 Android 设备遇到过此类问题&#xff0c;那么您来对地…