leetcode | 链表

news2024/12/27 14:03:19

01 链表知识点

1.1 基础知识

  • 线性表:零个或多个相同类型的数据元素的有限序列,一对一关系,所含数据元素个数n称为线性表的长度。

  • 线性表有两种物理结构(存储结构):顺序存储、链式存储

    • 线性表的顺序存储结构:用一段地址连续的存储单元依次存储线性表的数据元素。
      • 顺序存储结构三个属性:起始位置;线性表最大存储容量(数组长度MaxSize);线性表当前长度(length)。
    • 线性表的链式存储结构:用一组任意的存储单元存储线性表的数据元素,为了表示数据元素ai与其直接后继数据元素ai+1之间的逻辑关系,对ai来说,除了存储本身的信息之外,还要存储一个指示其直接后继元素存储位置的信息。
      • 存储数据元素信息的域叫数据域;存储直接后继元素位置的域叫指针域,指针域中存储的信息叫指针或链。
        • p结点的数域可以表示为p->data,存放的是p结点的数据元素;指针域可以表示为p->next,存放的是p结点直接后继结点的指针;*L表示链表L的头结点
      • 数据域和指针域组成的数据元素ai的存储映像叫结点(Node),n个结点链结成一个链表,即为线性表的链式存储结构

1.2 顺序存储结构 v.s. 单链表结构

顺序存储结构:

  1. 查找O(1),插入删除O(n)
  2. 需预分配存储空间,分大了浪费,分小了易溢出
  3. 若线性表需频繁查找,很少插入删除,用顺序结构

单链表结构:

  1. 查找O(n),插入删除在找到插入删除结点指针后O(1)
  2. 不需预分配存储空间,元素个数不受限
  3. 若线性表需频繁插入删除,用单链表结构
  4. 线性表元素个数未知或变化较大时,用单链表

链表只能顺序访问元素,要读取第十个元素,必须先读取前九个元素;顺序存储(数组)可以随机访问元素。

1.3 单链表

若链表中的每个结点只包含一个指针域,叫单链表。
单链表
单链表插入删除数据的时间复杂度也为O(n),但对于一次插入删除多个元素也是O(n)(顺序存储每次都是O(n)),因此对于插入删除较频繁的应用,单链表效率更高。

1.4 静态链表

用数组代替指针描述链表,用数组描述的链表叫静态链表。静态链表是给没有指针的高级语言设计的实现单链表能力的方法。
静态链表

  • 优点:插入删除操作时,只需修改游标不需移动元素,改进了顺序存储结构的插入删除操作需移动大量元素的缺点;
  • 缺点:没有解决连续存储分配带来的表长难以确定的问题;失去了顺序存储结构随机存取的特性。

1.5 循环链表

将单链表中终端结点的指针端由空指针改为指向头结点,使整个单链表形成一个环,这种头尾相接的单链表叫单循环链表,简称循环链表。

循环链表解决了如何从任一结点出发访问到链表的全部结点的问题。

1.6 双向链表

双向链表是在单链表各结点中,再设置一个指向其前驱结点的指针域(前驱指针*prioir,后继指针*next),双向链表也可以是循环表。

双向链表为某结点的前后结点操作带来方便,可以提升算法的时间性能,但由于每个结点都要记录两份指针,占用了空间,相当于用空间换时间。

注意,双向链表在插入删除时,需要更改两个指针变量,注意更改顺序。

  • 插入:1.搞定插入结点的前驱后继 2.搞定后结点的前驱 3.搞定前结点的后继。
  • 删除:1.把待删除结点的后结点赋值给前结点的后继 2.把待删除结点的前结点赋值给后结点的前驱。

02 算法题

2.1 两数相加

链接:https://leetcode.cn/leetbook/read/top-interview-questions-medium/xvw73v/

题目:给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
两数相加

解题思路: 使用两个指针,开始的时候分别指向两个链表的头节点。用他们相加和的个位数构造一个新的节点(因为一个节点只能存储一位数字),这两个指针每次运算完之后都要同时往后移一步,然后还要使用一个变量carry表示是否有进位。两个指针只要有一个不为空,或者carry不为0就继续循环。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        """
        使用两个指针,开始的时候分别指向两个链表的头节点。用他们相加和的个位数构造一个新的节点(因为一个节点只能存储一位数字),这两个指针每次运算完之后都要同时往后移一步,然后还要使用一个变量carry表示是否有进位。两个指针只要有一个不为空,或者carry不为0就继续循环
        """
        dummyNode=ListNode() # 定义一个哑节点,指向新链表头结点
        preNode=dummyNode # 定义当前节点的前一个节点
        carry=0 # 定义进位变量

        while l1 or l2 or carry: #当l1不为空或l2不为空或carry不为零时
            sum=carry # 定义两数各位之和变量
            # 链表1求和操作
            if l1: 
                sum+=l1.val
                l1=l1.next
            # 链表2求和操作
            if l2: 
                sum+=l2.val
                l2=l2.next
            
            # 创建新节点,preNode的next指针指向新节点
            # 因为链表节点只能存储一个数字,对sum取余
            preNode.next=ListNode(sum%10) 
            
            carry=sum//10 # 进位变量
            preNode=preNode.next # preNode后移一位
        
        #返回dummyNode的next指针指向的值,dummyNode指向新链表头结点
        return dummyNode.next 

2.2 奇偶链表

链接:https://leetcode.cn/leetbook/read/top-interview-questions-medium/xvdwtj/

题目:给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。
你必须在 O(1) 的额外空间复杂度和 O(n) 的时间复杂度下解决这个问题。
奇偶链表

解题思路:把奇数节点串到一起,我们称之为奇数链表,偶数节点串到一起,我们称之为偶数链表。最后再把偶数链表挂到奇数链表的后面即可。

在这里插入图片描述

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def oddEvenList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 链表长度小于等于1则返回原链表
        if head==None or head.next==None:
            return head
        
        oddHead=head # 奇数链表头节点
        oddCur=oddHead # 奇数链表当前节点(指针)
        evenHead=head.next # 偶数链表头节点
        evenCur=evenHead # 偶数链表当前节点(指针)

        while evenCur and evenCur.next: # 当链表未被遍历完
            oddCur.next=oddCur.next.next # 奇数节点串一起
            evenCur.next=evenCur.next.next #偶数节点串一起
            # 奇偶指针后移一位
            oddCur=oddCur.next
            evenCur=evenCur.next

        # 奇数链表与偶数链表合并,奇数链表末尾指向偶数链表头部
        oddCur.next=evenHead
        return oddHead

2.3 相交链表

链接:https://leetcode.cn/leetbook/read/top-interview-questions-medium/xv02ut/

题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
相交链表
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。

解题思路:题目意思是判断两个链表是否相交,如果相交就返回他们的相交的交点,如果不相交就返回null。链表相交指的是指针指向同一位置。

  • 思路1:先把第一个链表的节点全部存放到集合set中,然后遍历第二个链表的每一个节点,判断在集合set中是否存在,如果存在就直接返回这个存在的结点。如果遍历完了,在集合set中还没找到,说明他们没有相交
  • 思路2:先统计两个链表的长度,如果两个链表的长度不一样,就让链表长的先走,直到两个链表长度一样,这个时候两个链表再同时每次往后移一步,看节点是否一样,如果有相等的,说明这个相等的节点就是两链表的交点,否则如果走完了还没有找到相等的节点,说明他们没有交点,直接返回null即可。以下实现代码采用思路二
  • 思路3:双指针见题目链接
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
        '''先统计两个链表的长度,如果两个链表的长度不一样,就让链表长的先走,直到两个链表长度一样,这个时候两个链表再同时每次往后移一步,看节点是否一样,如果有相等的,说明这个相等的节点就是两链表的交点,否则如果走完了还没有找到相等的节点,说明他们没有交点,直接返回null即可'''
        listA=list()
        listB=list()

        # 统计链表长度
        ahead=headA
        bhead=headB # 定义一个新的链表用于统计原链表长度,否则原链表走到末端后为None
        while ahead:
            listA.append(ahead.val)
            ahead=ahead.next
        while bhead:
            listB.append(bhead.val)
            bhead=bhead.next
        lenA=len(listA)
        lenB=len(listB)

        # 较长的链表先走几步直到两链表等长
        while lenA!=lenB:
            if lenA>lenB:
                headA=headA.next
                lenA-=1
            else:
                headB=headB.next
                lenB-=1

        # 两链表等长后开始比较,走到最后若不相交则headA为空,若相交则跳出循环,headA为交点
        while headA!=headB:
            headA=headA.next
            headB=headB.next
        
        return headA

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

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

相关文章

优化改进YOLOv5算法之添加SE、CBAM、CA模块(超详细)

目录 1 SENet 1.1 SENet原理 1.2 SENet代码(Pytorch) 1.3 YOLOv5中加入SE模块 1.3.1 common.py配置 1.3.2 yolo.py配置 1.3.3 创建添加RepVGG模块的YOLOv5的yaml配置文件 2 CBAM 2.1 CBAM原理 2.2 CBAM代码(Pytorch) 2.3 YOLOv5中加入CBAM模块 2.3.1 common.py配…

敏捷是一种态度:有了敏捷建模,就有了敏捷需求

目 录01 缘起02 敏捷需求5W1H的思考‍‍‍‍‍‍03 关于敏捷需求体系的一些思考‍‍‍‍‍‍04 写在敏捷需求后的话01缘起对研发效能提升的研究,是近年来各家企业技术部门一直在研究的课题。早期,针对敏捷开发的实践,让大多技术管理者尝到…

114.(leaflet之家)leaflet空间判断-点与圆的空间关系

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>

每个开发人员都应该使用的可扩展和可维护的 React 项目结构

一个好的项目结构可以在理解代码库、灵活性和维护方面对项目的成功产生巨大影响。结构和维护不当的项目很快就会变成一团糟和可怕的遗产&#xff0c;没有人愿意与之共事。我现在将向您展示我在项目中经常使用的结构&#xff0c;并解释其背后的原因。这种结构应该是大规模应用程…

开源代码 | FMCW-MIMO雷达仿真MATLAB

本文编辑&#xff1a;调皮哥的小助理 本程序来源&#xff1a;https://github.com/ekurtgl/FMCW-MIMO-Radar-Simulation&#xff0c;作者是阿拉巴马大学博士生艾库特格尔&#xff0c;研究方向主要是雷达信号处理人类活动识别以及雷达数据的机器学习应用&#xff0c;这份比较新的…

STM32MP157驱动开发——4G通信模块驱动

STM32MP157驱动开发——4G通信模块驱动一、简介二、驱动开发1.高新兴 ME3630 驱动开发驱动修改添加 ECM 支持程序配置 Linux 内核ppp拨号功能测试ECM 联网测试ME3630 4G 模块 GNSS 定位测试2.移远EC20 4G驱动开发驱动修改配置 Linux 内核EC20 ppp 拨号上网移远 GobiNET 驱动移植…

go语言学习(一):Mac环境安装及初始化

​ ​为什么要学习go语言? 1、简洁&#xff0c;快速&#xff0c;安全&#xff1b; ​ ​2、并行&#xff0c;有趣&#xff0c;开源​&#xff1b; 3、内存管理&#xff0c;数据安全&#xff0c;编译迅速 首先&#xff0c;去官网&#xff1a;https://golang.google.cn/dl…

面向对象3(多态、多态调用成员函数的特点、多态的优势和弊端及改进、包、final、权限修饰符、代码块、抽象方法和抽象类、接口、内部类)

1、多态 2、多态调用成员函数的特点 示例如下&#xff1a; 理解&#xff1a; 因为是Animal类型的&#xff0c;所以在输出name时会在父类继承下来的变量里面找 &#xff0c;没有就报错。而一般是先找自己再找父类继承下来的。 3、多态的优势和弊端及改进 优势&#xff1a; 弊端…

Arduino——野火GPS模块

GPS模块 文章目录GPS模块前言一、Arduino代码前言 手上还有一个GPS&#xff0c;用arduino做模块很方便&#xff0c;打算和短信模块结合&#xff0c;短信模块上次已经使用完成了&#xff0c;这次学习一下GPS模块 看模块很容易知道&#xff0c;这个模块用的是串口通信&#xff…

基于STM32智能家居控制系统软件设计及实现

1.1 系统流程图 智能家居控制系统的软件设计主要使用Keil uVision5进行STM32主烧录程序的编写&#xff0c;主程序完成的功能主要为接收并判断语音识别模块传过来的信息&#xff0c;然后根据满足条件的不同进行对应的操作。例如&#xff0c;当语音模块传过来的信息为“打开电视…

top详解--查看cpu及内存使用情况

top详解--查看cpu及内存使用情况 参考链接:http://t.zoukankan.com/guoyu1-p-12237660.html 一、top命令 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。 运行 top 命令后,CPU 使用状态会以全屏的方式显示,…

基于Java+SpringBoot+vue+element实现婚纱摄影网系统

基于JavaSpringBootvueelement实现婚纱摄影网系统 &#x1f345; 作者主页 超级帅帅吴 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 文章目录基于JavaSpringBootvueelement实现婚纱摄影网系统前言介绍&…

Flask中的后端并发思考(以Mysql:too many connections为例)

之前写过一篇《CentOS 下部署NginxGunicornSupervisor部署Flask项目》&#xff0c;最近对该工程的功能进行了完善&#xff0c;基本的功能单元测试也做了。觉得也是时候进行一下压力测试了&#xff0c;所以利用Jmeter对部署到服务器的项目进行了简单的压力测试。在之前的笔记中写…

10个 Python 高效编程小技巧

初识Python语言&#xff0c;觉得python满足了你上学时候对编程语言的所有要求。python语言的高效编程技巧让那些曾经苦逼学了四年c或者c的人&#xff0c;兴奋的不行不行的&#xff0c;终于解脱了。高级语言&#xff0c;如果做不到这样&#xff0c;还扯啥高级呢&#xff1f; 01…

【密码学】HMAC与HS256算法

哈希算法加盐 传统的哈希算法&#xff1a; digest hash(input)因为相同的输入会产生相同的输出&#xff0c;所以想要加盐&#xff0c;加盐的目的就在于&#xff0c;使输入有所变化&#xff1a; digest hash(salt input)这个salt可以看作是一个额外的“认证码”&#xff0…

ChatGPT 使用 API 进行 Postman 调用测试

当获得 ChatGPT 的 API Key 以后&#xff0c;想使用 Postman 来进行一下调用。调用的方法为 POST。需要设置几个参数。我们希望使用的 EndPoint 是&#xff1a;API EndPoint访问使用的 EndPoint 是&#xff1a;https://api.openai.com/v1/completions授权方法授权的方法使用的是…

FortiGate FGCP HA 配置文档

概述 FortiOS 提供 6 种冗余解决方案&#xff0c;工业标准的 VRRP 和 5 种专有的解决方案&#xff1a; FortiGate Cluster Protocol (FGCP) high availability&#xff0c;FortiGate Session Life Support Protocol (FGSP) high availability&#xff0c;Session-Aware Load …

Spring Cloud LoadBalancer(负载均衡)

简介 了解过Spring Cloud&#xff0c;就知道&#xff0c;之前Spring Cloud中默认的负载均衡组件为ribbon&#xff0c;ribbon是Netflix开源的组件&#xff0c;但是目前已经停止更新了。所以Spring官方推出了Spring Cloud LoadBalancer。而且Spring Cloud LoadBalancer是目前唯一…

win11下通过qemu 安装win10 arm系统

安装qemu QEMU for Windows – Installers (64 bit) 我选了最新的20221230的版本&#xff0c;我将其安装在c:\qemu7\下&#xff0c;另外在环境变量中加入这个路径 然后在别的盘上建立一个路径&#xff0c;名称随意&#xff0c;不要有中文和空格即可&#xff0c;我放在了e:\qe…

电脑蓝屏提示错误代码0X000000B4怎么办?

电脑蓝屏可以说是Windows的一个常见问题了。蓝屏状况数不胜数&#xff0c;关键还得看是何终止代码。 如果电脑蓝屏&#xff0c;提示错误代码0X000000B4是什么意思&#xff1f;这是由于Windows不能启动显卡驱动&#xff0c;从而无法进入图形界面。 蓝屏错误0X000000B4可能由驱…