【数据结构】链表常见题目
文章目录
- 链表
- 合并两个有序链表
- 反转链表
- 复制带随机指针的链表
- 环形链表
- 环形链表II
- 相交链表
- 移除链表元素
- 链表中倒数第k个节点
- 链表分割
- 链表的回文结构
- 链表的中间节点
- 旋转链表
- 链表排序
- 链表求和 (逆序求)
- 链表求和II (正序求)
- 重排链表
- 奇偶链表
- 反转链表II <==> 链表内指定区间反转
- 删除链表中的节点
- 删除有序链表当中重复的元素I
- 删除有序链表当中重复的元素II
- 合并K个升序链表
- K个一组反转链表
- 交换链表中的节点
- 二进制链表转整数
- 链表随机节点
链表
合并两个有序链表
https://leetcode.cn/problems/merge-two-sorted-lists/
1.定义一个哨兵位节点和一个tail节点标志尾节点
2.遍历两条有序链表,谁小就链接谁
3.最后还剩一条链表是没有遍历完成的,那么就让tail节点链接它
class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {//1.新建哨兵位节点ListNode* phead = new ListNode(-1);ListNode* tail = phead;//2.谁小就链接谁while(list1 && list2){if(list1->val > list2->val){tail->next = list2;tail = list2;list2 = list2->next;}else {tail->next = list1;tail = list1;list1 = list1->next;}}//3.判断谁还没有链接完if(list1) tail->next = list1;if(list2) tail->next = list2;return phead->next;}
};
反转链表
https://leetcode.cn/problems/reverse-linked-list/description/
prev:记录前一个节点 cur:当前遍历到的节点 next:保存cur的下一个节点
- 先保存下一个节点 然后更改cur的指向,指向前一个节点
- 然后迭代往后走
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* prev = nullptr;//记录前一个节点ListNode* cur = head;//记录当前节点ListNode* next = nullptr;//记录下一个节点while(cur){next = cur->next;//先保存下一个节点cur->next = prev;//更改当前节点指向//prev cur next 迭代往后走prev = cur;cur = next;}return prev;}
};
复制带随机指针的链表
https://leetcode.cn/problems/copy-list-with-random-pointer/
1.在原链表节点之后拷贝一个节点

2.处理拷贝节点的random指针
- 注意:拷贝节点的random指针指向的节点是其原链表节点的random指针指向的节点的下一个节点
- 坑点:有可能cur->random是空,也就是原来节点的random指针为空,那么当前拷贝节点的random指针也应该为空,否则cur->random->next 就会对空指针解引用!

3.分离两条链表
- 最好定义一个哨兵位节点和一个tail指针用于标记链接拷贝链表,
cur CopyCur next三者的关系重新处理

class Solution {public:Node* copyRandomList(Node* head) {if(head == nullptr ) return nullptr;//1.在原节点后面copy一个节点Node* cur = head;while(cur){Node* copy = new Node(cur->val);//拷贝节点Node* next = cur->next;//cur copy next 链接cur->next = copy;copy->next = next;cur = next;//继续复制下一个节点}//2.处理拷贝节点的random指针cur = head;while(cur){Node* curCopy = cur->next;//cur的拷贝节点curCopy->random = cur->random == nullptr?nullptr:cur->random->next;cur = curCopy->next;}//3.拆离拷贝链表cur = head;Node* pnewHead = new Node(-1);//哨兵位Node* tail = pnewHead;while(cur){//cur copyCur next Node* copyCur = cur->next;Node* next = copyCur->next;copyCur->next = nullptr;//让拷贝节点独立存在tail->next = copyCur;tail = tail->next;//重新处理链接关系,向后走cur->next = next;cur = next;}return pnewHead->next;}
};
环形链表
https://leetcode.cn/problems/linked-list-cycle/description/
方法:使用快慢指针,二者从头开始走,一个一次走两步,一个一次走一步,当二者相遇的时候,说明有环
class Solution {
public:bool hasCycle(ListNode *head) {//链表为空//注意:一个节点也能成环! 自己指向自己if(!head) return false;//快慢指针ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;//二者相遇 注意:该条件不能放在上面!!!因为最初fast和slow都指向head,该条件应该放在下面if(slow == fast) return true;}return false;}
};
延申1:fast一次走两步,slow一次走一步,为什么一定能相遇?会不会在环里错过,永远遇不上
结论:slow一次走一步,fast一次走两步,如果存在环,slow和fast一定会在环内相遇
1.slow和fast,如果有环,一定是fast先进环,这时slow走了入环前距离的一半
2.随着slow进环,fast已经在环里面走了一段距离了(距离的多少跟环的大小有关)
- 假设slow进环的时候,slow和fast的距离为N,fast开始追赶slow
3.slow一次走一步,fast一次走两步,二者的距离变化为:N N- 1 N -2 … 0,当二者的距离变为0的时候,就是相遇了
延申2:fast一次走n步(n>2),slow一次走一步,fast和slow能相遇吗
结论:fast一次走n步(n>2),slow一次走一步,不一定会相遇
- 假设有环,fast一次走n步,slow一次走1步,fast和slow的距离不断减少n-1步
例子:假设fast一次走3步,如果slow进环之后,slow和fast的距离为N
如果N为偶数,那么二者之间的距离变化为:N N - 2 N - 4 … 2 0,此时二者相遇
如果N为计数,那么二者之间的距离变化为:N N - 2 N - 4 … 1 -1 ,二者距离变为-1,意味着fast超越了slow,此时fast和slow的距离为C -1 (假设C为环的大小)
- 如果C - 1 为偶数,那么下一轮fast可以追上slow,二者相遇
- 如果C - 1 为奇数,那么二者永远追不上
环形链表II
https://leetcode.cn/problems/linked-list-cycle-ii/description/
做法:
1.先看是否有环,快慢指针,fast一次走两步,slow一次走一步,如果存在环,fast和slow一定会相遇
2.假设相遇点为meetnode,一个指针从链表的头开始走,一个指针从相遇点开始走,二者一次走一步,当二者相遇的时候,该位置就是入环节点

class Solution {
public:ListNode *detectCycle(ListNode *head) {if(!head) return nullptr;//快慢指针ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;//二者相遇 注意:该条件不能放在上面!!!因为最初fast和slow都指向head,该条件应该放在下面if(slow == fast) {//分别从相遇点和链表头开始走,一次走一步 此时相遇就是入环位置ListNode* meet = slow;slow = head;while(slow != meet) {slow = slow->next;meet = meet->next;}return meet;}}return nullptr; //没有环}
};
相交链表
https://leetcode.cn/problems/intersection-of-two-linked-lists/description/
方法1:将A链表的所有节点放到容器当中(要放地址,不能放值),然后遍历B链表,看能否在容器当中找到该元素,如果找到,那么该节点就是相交节点
class Solution {
public://方法1:用容器保存其中一个链表的节点,然后遍历另外一个链表进行比对ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {multiset<ListNode*> s;ListNode* cur = headA;while(cur) {s.insert(cur);cur = cur->next;}cur = headB;while(cur){cout << cur->val << endl;if(s.find(cur) != s.end()) return cur;cur = cur->next;}return nullptr;//不相交}
};
方法2:A中的每个结点和B分别比较(B和A比较也可以),看二者的地址是否一致 - O(N*M)
class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* curA = headA;ListNode* curB = headB;while(curA) //确定一个A节点{curB = headB;while(curB)//遍历整条B链表{if(curA == curB){return curA;}curB = curB ->next;}curA = curA->next;}return nullptr;}
};
方法3:
1.先统计两条链表的长度,假设二者长度差距为gap
2.长链表先往后走gap步,然后长短链表一起往后走,如果相遇,那么就是相交节点
class Solution {public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {if(!headA || !headB) return nullptr;//1.统计两条链表的长度int lenA = 0;int lenB = 0;ListNode* cur = headA;while(cur) lenA++,cur = cur->next;cur = headB;相关文章:
【数据结构】链表常见题目
文章目录 链表合并两个有序链表反转链表复制带随机指针的链表环形链表环形链表II相交链表移除链表元素链表中倒数第k个节点链表分割链表的回文结构链表的中间节点旋转链表链表排序链表求和 (逆序求)链表求和II (正序求)重排链表奇偶链表反转链表II <==> 链表内指定区间反…...
多家企业加入即将在2024年发射的量子卫星SpeQtral-1任务
近日,总部位于新加坡的量子通信技术公司SpeQtral宣布将与纳米航空电子公司NanoAvionics和卫星光子学公司Mbryonics合作执行即将到来的SpeQtral-1量子密钥分发(Quantum Key Distribution, QKD)卫星任务。NanoAvionics被选为卫星平台提供商&…...
shell脚本基础
目录 前言 一、概述 (一)、shell脚本基础概念 (二)、shell的类型 二、Shell变量 (一)、组成 1.变量名 2.变量值 (二)、类型 1.系统内置变量(环境变量) 2.自定…...
创建maven的Springboot项目出现错误:Cannot access alimaven
创建maven的Springboot项目出现错误:Cannot access alimaven 1)问题2) 分析问题3)解决问题 1)问题 创建maven的Springboot项目出现错误: Cannot access alimaven (http://maven.aliyun.com/nexus/content/groups/p…...
神经网络基础-神经网络补充概念-32-神经网络与大脑
概念 神经网络(Neural Networks)是受到生物神经系统启发而设计的机器学习模型,用于处理和学习复杂的数据模式。尽管神经网络的设计和工作原理与大脑有一些相似之处,但它们并不完全相同,以下是神经网络和大脑之间的一些…...
linux自动填充密码及提示信息
背景:需要自动创建nvc的登录密码 sudo apt-get install expect expect 是由Don Libes基于Tcl(Tool Command Language )语言开发的,主要应用于自动化交互式操作的场景,借助Expect处理交互的命令,可以将交互…...
IC设计中主要的EDA工具有哪些? (内附EDA虚拟机安装资源)
EDA工具的使用涵盖了芯片的功能设计、综合、验证、物理设计等环节,更是被称作“芯片设计的工作母机”。下面就来为大家具体介绍一下常见的EDA工具。(需要EDA虚拟机安装资源文末可领取~) 什么是EDA? EDA是电子设计自动化…...
Zabbix配置通用的TCP/IP:port监控项
我们经常的用接口,比如说FTP、HTTP、DNS、数据库接口,都可以用IP:PORT方式探测其是否存活,那么我们去繁就简,就简单监控一下IP:PORT吧! 1、新建主机: 填入主机名称、群组、Agent可以不填&…...
【RocketMQ】SpringBoot集成RocketMQ
SpringBoot集成RocketMQ 首先依旧是引入依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.2</version> </dependency>然后就可以编写发送不同类…...
思腾云计算
思腾合力受邀参加第七届世界智能大会,届时在会上展出思腾合力 AI 服务器。诚挚邀请与会者来思腾展位(S10-B04)参观与交流,领取七彩虹电竞机械键盘与鼠标、正版NVIDIA信仰尺、公牛魔方智能USB插座、超大桌面鼠标垫等精美礼品。 由天…...
前端面试:【HTML】语义化标签、表单、媒体元素
HTML(超文本标记语言)是构建网页内容的基础,它通过一系列标签来描述页面的结构和内容。在这篇文章中,我们将探讨HTML的基础知识,包括语义化标签、表单和媒体元素。 语义化标签:赋予内容更多意义 语义化标签…...
2024浙大MBA/MEM/MPA四个月冲刺备考策略
近期收到很多考生的咨询:距离联考就仅剩四个多月的时间,这个管理类联考的难度如何?主要考些什么内容?现在才开始备考还有希望上岸浙大吗?是不是要等到明年在开始备考比较合适?那么今天在这里小立老师就跟大…...
Element通过v-for循环渲染的form表单校验
需求:有个表单信息是v-for渲染的,例如下图,通过循环遍历实现新增和删除模块,按照平时的写法实现校验,是不能实现我们想要的效果,根据这个需求,我找到了一个解决方法 1.HTML <el-form ref&qu…...
精彩回顾 | 迪捷软件出席2023ATC汽车电子与软件技术周
2023年8月18日,由ATC汽车技术会议主办,上海市集成电路行业协会支持的“2023ATC汽车电子与软件技术周”在上海市圆满落幕。迪捷软件上海参展之行圆满收官。 ▲开幕式 本次峰会汇聚了整车厂、汽车零部件集团、软硬件方案提供商、软件工具供应商、软件测试…...
树莓派的自启动与桌面应用程序
目录 1 打开终端自启动 .bashrc 2 触发时机较早的开机自启动rc.local 3 桌面应用程序 4 触发时机较晚的的开机自启动 autostart 1 打开终端自启动 .bashrc .bashrc的程序也可以在开机时进行自启动,但是每一次打开终端时同样会运行一遍,所以只需…...
RabbitMQ面试题
1. 什么是MQ MQ 就是消息队列。是软件和软件进行通信的中间件产品 2. MQ的优点 异步处理 - 相比于传统的串行、并行方式,提高了系统吞吐量。 应用解耦 - 系统间通过消息通信,不用关心其他系统的处理。 流量削锋 - 可以通过消息队列长度控制请求量…...
Kubernetes二进制部署方案
目录 一、环境准备 2.1、主机配置 2.2、安装 Docker 2.3、生成通信加密证书 2.3.1、生成 CA 证书(所有主机操作) 2.3.2、生成 Server 证书(所有主机) 2.3.3、生成 admin 证书(所有主机) 2.3.4、生成 proxy 证书 三、部署 …...
Android 13 开启关闭飞行模式
一.背景 由于客户定制的Settings里面需要开启和关闭飞行模式,所以需要实现此功能。 二.前提条件 首先应用肯定要是系统应用,并且导入framework.jar包,具体可以参考: Android 应用自动开启辅助(无障碍)功能并使用辅助(无障碍)功能_android 自动开启无障碍服务_龚礼鹏的博客…...
C++学习笔记总结练习:EffectiveSTL
文章目录 使用STL库的55条建议1.慎重选择容器的类型2.不要试图编写独立于容器的代码3.确定容器中的对象拷贝正确且高效4.调用empty判断是否为空,而不是size5.区间成员函数优于与之对应单元素成员函数6.如果容器中包含了通过new操作创建的指针,切记在容器…...
SQL Developer中的Data Redaction
SQL Developer中的Data Redaction用起来比命令行方便多了。可以选定表或视图,右键点击“遮盖保护”菜单。 但赋权方面有需要注意的地方。 假设Redact Admin是SYS,Redact User是HR。虽然SYS具备所有权限,但还是报以下错误。其实这个错误是针…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
