【数据结构刷题集】链表经典习题
😽PREFACE
🎁欢迎各位→点赞👍 + 收藏⭐ + 评论📝
📢系列专栏:数据结构刷题集
🔊本专栏涉及到题目是数据结构专栏的补充与应用,只更新相关题目,旨在帮助提高代码熟练度
💪种一棵树最好是十年前其次是现在
移除链表元素
题目链接:https://leetcode.cn/problems/remove-linked-list-elements/description/


struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode* prev=NULL,*cur=head;while(cur){if(cur->val==val){prev->next=cur->next;free(cur);cur=prev->next;}else{prev=cur;cur=cur->next;}}return head;
}
提交一下,我们会发现执行出错。


正确代码:
struct ListNode* removeElements(struct ListNode* head, int val){struct ListNode* prev=NULL,*cur=head;while(cur){if(cur->val==val){if(cur==head){//头删head=cur->next;free(cur);cur=head;}else{prev->next=cur->next;free(cur);cur=prev->next;} }else{prev=cur;cur=cur->next;}}return head;
}
链表的中间结点
题目链接:https://leetcode.cn/problems/middle-of-the-linked-list/description/


正确代码:
//尺取法
struct ListNode* middleNode(struct ListNode* head){struct ListNode* slow=head,*fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;}return slow;
}
链表中倒数第k个结点
题目链接:https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&&tqId=11167&rp=2&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking


struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {struct ListNode* fast=pListHead,*slow=pListHead;while(k--){fast=fast->next;}while(fast){slow=slow->next;fast=fast->next;}return slow;;
}
结果代码运行不过:


正确代码:
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {struct ListNode* fast=pListHead,*slow=pListHead;while(k--){if(fast==NULL)//防止越界{return NULL;}fast=fast->next;}while(fast){slow=slow->next;fast=fast->next;}return slow;;
}
反转链表
题目链接:https://leetcode.cn/problems/reverse-linked-list/description/

法一:画图+迭代

//画图+迭代
struct ListNode* reverseList(struct ListNode* head){struct ListNode* prev,*cur,*next;prev=NULL,cur=head,next=head->next;while(cur){//反转cur->next=prev;//迭代prev=cur;cur=next;next=next->next;}return prev;
}
这个只是最基本的逻辑,一运行发现还是过不了

//画图+迭代
struct ListNode* reverseList(struct ListNode* head){struct ListNode* prev,*cur,*next;prev=NULL,cur=head,next=head->next;while(cur){//反转cur->next=prev;//迭代prev=cur;cur=next;if(next)next=next->next;}return prev;
}
再次提交,发现还是过不去:

正确代码1:
//画图+迭代
struct ListNode* reverseList(struct ListNode* head){if(head==NULL)return NULL;struct ListNode* prev,*cur,*next;prev=NULL,cur=head,next=head->next;while(cur){//反转cur->next=prev;//迭代prev=cur;cur=next;if(next)next=next->next;}return prev;
}
法二:头插
为什么能想到头插呢?因为头插的顺序与链表的顺序刚好相反。
正确代码2:
//头插
struct ListNode* reverseList(struct ListNode* head){struct ListNode* cur=head, *newhead=NULL;while(cur){struct ListNode* next=cur->next;//头插cur->next=newhead;newhead=cur;cur=next;}return newhead;
}
合并两个有序链表
题目链接:https://leetcode.cn/problems/merge-two-sorted-lists/description/

法一:不带哨兵位头结点

//不带哨兵位头结点
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){struct ListNode* cur1=list1,*cur2=list2;struct ListNode* head=NULL,*tail=NULL;while(cur1&&cur2){if(cur1->val<cur2->val){if(head==NULL){head=tail=cur1;}else{tail->next=cur1;tail=tail->next;}cur1=cur1->next;}else{if(head==NULL){head=tail=cur2;}else{tail->next=cur2;tail=tail->next;}cur2=cur2->next;}}if(cur1){tail->next=cur1;}if(cur2){tail->next=cur2;}return head;
}

正确代码1:
//不带哨兵位头结点
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){//如果链表为空,返回另一个if(list1==NULL){return list2;}if(list2==NULL){return list1;}struct ListNode* cur1=list1,*cur2=list2;struct ListNode* head=NULL,*tail=NULL;while(cur1&&cur2){if(cur1->val<cur2->val){if(head==NULL){head=tail=cur1;}else{tail->next=cur1;tail=tail->next;}cur1=cur1->next;}else{if(head==NULL){head=tail=cur2;}else{tail->next=cur2;tail=tail->next;}cur2=cur2->next;}}if(cur1){tail->next=cur1;}if(cur2){tail->next=cur2;}return head;
}
法二:带哨兵位头结点

正确代码2:
//带哨兵位头结点
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){struct ListNode* cur1=list1,*cur2=list2;struct ListNode* guard=NULL,*tail=NULL;guard=tail=(struct ListNode*)malloc(sizeof(struct ListNode));tail->next=NULL;while(cur1&&cur2){if(cur1->val<cur2->val){tail->next=cur1;tail=tail->next;cur1=cur1->next;}else{tail->next=cur2;tail=tail->next;cur2=cur2->next;}}if(cur1){tail->next=cur1;}if(cur2){tail->next=cur2;}struct ListNode* head=guard->next;//防止内存泄漏free(guard);return head;
}
链表分割
题目链接:https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking


class Partition {
public:ListNode* partition(ListNode* pHead, int x) {struct ListNode* lessguard,*lesstail,*greaterguard,*greatertail;lessguard=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));greaterguard=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));lesstail->next=greatertail->next=NULL;struct ListNode* cur=pHead;while(cur){if(cur->val<x){lesstail->next=cur;lesstail=lesstail->next;}else{greatertail->next=cur;greatertail=greatertail->next;}cur=cur->next;}lesstail->next=greaterguard->next;pHead=lessguard->next;free(greaterguard);free(lessguard);return pHead;}
};
运行一下:

由于牛客不提供用例错误,我们可以转到力扣官网上查。当然了,也可以把我们写的用例往代码带,看看哪出错了。

正确代码:
class Partition {
public:ListNode* partition(ListNode* pHead, int x) {struct ListNode* lessguard,*lesstail,*greaterguard,*greatertail;lessguard=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));greaterguard=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));lesstail->next=greatertail->next=NULL;struct ListNode* cur=pHead;while(cur){if(cur->val<x){lesstail->next=cur;lesstail=lesstail->next;}else{greatertail->next=cur;greatertail=greatertail->next;}cur=cur->next;}lesstail->next=greaterguard->next;greatertail->next=NULL;//不能忽略pHead=lessguard->next;free(greaterguard);free(lessguard);return pHead;}
};
链表的回文结构
题目链接:https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId=49&&tqId=29370&rp=1&ru=/activity/oj&qru=/ta/2016test/question-ranking


正确代码:
//找中间节点
struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head, *fast = head;while (fast && fast->next) {slow = slow->next;fast = fast->next->next;}return slow;
}
//反转
struct ListNode* reverseList(struct ListNode* head) {struct ListNode* cur = head;struct ListNode* newhead = NULL;while (cur) {struct ListNode* next = cur->next;//头插cur->next = newhead;//迭代newhead = cur;cur = next;}return newhead;
}class PalindromeList {public:bool chkPalindrome(ListNode* A) {struct ListNode* mid=middleNode(A);struct ListNode* rHead=reverseList(mid);struct ListNode* curA=A;struct ListNode* curR=rHead;while(curA&&curR){if(curA->val!=curR->val){return false;}else{curA=curA->next;curR=curR->next;}}return true;}
};
相交链表
题目链接:https://leetcode.cn/problems/intersection-of-two-linked-lists/description/


正确代码:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* tailA=headA,*tailB=headB;int lenA=0,lenB=0;while(tailA){lenA++;tailA=tailA->next;}while(tailB){lenB++;tailB=tailB->next;}//不相交的情况,不写的话leetcode也不会判错if(tailA!=tailB){return NULL;}int gap=abs(lenA-lenB);struct ListNode* longList=headA,*shortList=headB;if(lenA<lenB){longList=headB;shortList=headA;}while(gap--){longList=longList->next;}while(longList!=shortList){longList=longList->next;shortList=shortList->next;}return shortList;
}
环形链表
题目链接:https://leetcode.cn/problems/linked-list-cycle/description/


正确代码:
bool hasCycle(struct ListNode *head) {struct ListNode* slow=head,*fast=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(fast==slow){return true;}}return false;
}
环形链表II
题目链接:https://leetcode.cn/problems/linked-list-cycle-ii/description/

法一:双指针

正确代码1:
struct ListNode *detectCycle(struct ListNode *head) {struct ListNode* slow=head,*fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;if(slow==fast){//相遇struct ListNode* meetNode=slow;//公式while(meetNode!=head){meetNode=meetNode->next;head=head->next;}return head;}}return NULL;
}
法二:转化成链表相交

正确代码2:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {struct ListNode* tailA=headA,*tailB=headB;int lenA=0,lenB=0;while(tailA){lenA++;tailA=tailA->next;}while(tailB){lenB++;tailB=tailB->next;}//不相交的情况,不写的话leetcode也不会判错if(tailA!=tailB){return NULL;}int gap=abs(lenA-lenB);struct ListNode* longList=headA,*shortList=headB;if(lenA<lenB){longList=headB;shortList=headA;}while(gap--){longList=longList->next;}while(longList!=shortList){longList=longList->next;shortList=shortList->next;}return shortList;
}struct ListNode *detectCycle(struct ListNode *head) {struct ListNode* slow=head,*fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;if(slow==fast){struct ListNode* meetNode=slow;struct ListNode* list1=meetNode->next;struct ListNode* list2=head;meetNode->next=NULL;return getIntersectionNode(list1,list2);}}return NULL;
}
复制带随机指针的链表
题目链接:https://leetcode.cn/problems/copy-list-with-random-pointer/description/


正确代码:
struct Node* copyRandomList(struct Node* head) {//1.拷贝结点插入原结点的后面struct Node* cur=head;while(cur)//遍历整个链表{//插入struct Node* copy=(struct Node*)malloc(sizeof(struct Node));copy->val=cur->val;struct Node* next=cur->next;//cur copy nextcur->next=copy;copy->next=next;cur=next;}//2.拷贝random结点cur=head;while(cur){struct Node* copy=cur->next;if(cur->random==NULL){copy->random=NULL;}else{copy->random=cur->random->next;}cur=cur->next->next;}//3.拆组struct Node* copyHead=NULL,*copyTail=NULL;cur=head;while(cur){struct Node* copy=cur->next;struct Node* next=copy->next;//copy尾插if(copyHead==NULL){copyHead=copyTail=copy;}else{copyTail->next=copy;copyTail=copyTail->next;}//恢复原链表cur->next=next;cur=next;}return copyHead;
}
相关文章:

【数据结构刷题集】链表经典习题
😽PREFACE🎁欢迎各位→点赞👍 收藏⭐ 评论📝📢系列专栏:数据结构刷题集🔊本专栏涉及到题目是数据结构专栏的补充与应用,只更新相关题目,旨在帮助提高代码熟练度&#x…...

JavaSE(3.27) 异常
学习不要眼高手低,学习是一点点积累的。即使你现在很菜,坚持学一个学期不会差的!只要花时间学习,每天都是进步的,这些进步可能你现在看不到,但是不要小瞧了积累效应,30天,60天&#…...
【看门狗】我说的是定时器不是狗啊
单片机在运行中死机了,你或许只能按2下电源键(重启)或1下复位键。 这里简单说一下重启和复位: 从RESET引脚复位,只有MCU复位。而外设看情况,有的可能会有MCU同步复位或者重新初始化。也有可能一些保持复位…...

24万字智慧城市顶层设计及智慧应用解决方案
本资料来源公开网络,仅供个人学习,请勿商用,如有侵权请联系删除。部分资料内容: 4.8 机房消防系统 4.8.1消防系统概况 根据本工程机房消防系统的特殊要求,整个消防系统由火灾报警系统、消防联动系统和气体灭火系统三部…...
跨境电商卖家工具——跨境卫士内容介绍
一、简介 跨境卫士是一款集合多种跨境电商工具的综合软件,由知名跨境电商服务商跨境通开发。跨境卫士可以帮助卖家完成海外物流管理、订单处理、报关报税、市场营销等多项任务,同时还提供数据分析、客户服务、运营管理等一系列支持功能,方便卖…...

Redis 常用基本命令
关于 redis 的常用基本命令 目录 关于 redis 的常用基本命令 1. 关于 key 的操作 2. HyperLogLog 求近似基数 3. 排序相关命令 4. Limit 限制查询 1. 关于 key 的操作 判断某个 key 是否存在 # 格式: exists key exists name# 存在name 返回1 # 不存在name 返回0 查找或…...

【Leetcode】队列的性质与应用
文章目录225. 用队列实现栈示例:提示:分析:题解:622. 设计循环队列示例:提示:分析:题解:225. 用队列实现栈 请你仅使用两个队列实现一个后入先出(LIFO)的栈&…...

开启新航路,拓尔思发力AIGC市场 | 爱分析调研
2022年,随着AI聊天机器人GhatGPT在世界范围内持续火爆,极具创意、表现力、个性化且能快速迭代的AIGC技术成功破圈,成为全民讨论热点。 AIGC是指在确定主题下,由算法模型自动生成内容,包括单模态内容如文本、图像、音频…...

RK3568平台开发系列讲解(调试篇)Linux 内核的日志打印
🚀返回专栏总目录 文章目录 一、dmseg 命令二、查看 kmsg 文件三、调整内核打印等级沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将 Linux 内核的日志打印进行梳理。 一、dmseg 命令 在终端使用 dmseg 命令可以获取内核打印信息,该命令的具体使用方法如下所…...

hadoop之MapReduce框架原理
目录 MapReduce框架的简单运行机制: Mapper阶段: InputFormat数据输入: 切片与MapTask并行度决定机制: job提交过程源码解析: 切片逻辑: 1)FileInputFormat实现类 进行虚拟存储 &#x…...

JavaEE简单示例——SpringMVC的简单数据绑定
简单介绍: 在前面我们介绍过如何将我们自己创建的类变成一个servlet来处理用户发送的请求,但是在大多数的时候,我们在请求 的时候会携带一些参数,而我们现在就开始介绍我们如何在Java类中获取我们前端请求中携带的参数。首先&…...
耗时的同步请求自动转异步请求
耗时的同步请求自动转异步请求问题描述问题处理代码实现问题描述 现在在项目中碰到一个情况,导出数据到excel,在数据量比较下的时候直接下载,在数据量比较大时保存到服务的文件列表,后续再供用户下载。 也就是需要避免前端因后端…...

React常见的hook
目录 useState useEffect useRef useContext useCallback useMemo useState const [初始值,修改值的方法] useState( 初始值 ) 我们用useState定义一个初始值,可以打印看一下结果 console.log(useState(10)) // [10, ƒ] 结果是一个数组…...
Oracle集群管理ASM-扩容磁盘组报错ora-15137
1 内容描述 今日对19c集群磁盘组进行扩容, [rootdb1 ~]# oracleasm createdisk DATA7 /dev/sdm1 Writing disk header: done Instantiating disk: done [rootdb1 ~]# oracleasm createdisk DATA8 /dev/sdn1 Writing disk header: done Instantiating disk: done 使…...

TryHackMe-biteme(boot2root)
biteme 远离我的服务器! 端口扫描 循例 nmap Web枚举 打开一看是一个默认页面 扫一波 打thm这么久,貌似还是第一次见带验证码的登录 信息有限,对着/console再扫一波 查看/securimage 但似乎没有找到能利用的信息 回到console, 在源码发现…...

vue开发常用的工具有哪些
个人简介:云计算网络运维专业人员,了解运维知识,掌握TCP/IP协议,每天分享网络运维知识与技能。座右铭:海不辞水,故能成其大;山不辞石,故能成其高。个人主页:小李会科技的…...

数组,排序,查找
数组可以存放多个同一类型的数据,数组也是一种数据类型,是引用类型。 数组可以通过下标来访问元素下标是从0开始编号的比如第一个元素就是hens[0]数组定义,数据类型 数组名[] new 数据类型[大小];int a[] new int[5];动态初始化 import ja…...
redis中序列化后的对象后当如何修改
redis中序列化Redis 中存储的序列化对象是不可变需要频繁修改对象属性, 我存储对象为hash结构如何?总结君问归期未有期,巴山夜雨涨秋池。——唐代李商隐《夜雨寄北》 Redis 中存储的序列化对象是不可变 在 Redis 中存储的序列化对象是不可变的,因为它们…...

膜拜!阿里自爆十万字Java面试手抄本,脉脉一周狂转50w/次
最近,一篇题为《阿里十万字Java面试手抄本》的文章在社交媒体平台上引起了广泛关注。这篇文章由一位阿里工程师整理了阿里Java面试的经验,并分享给了大家。这篇文章一经发布,就在短时间内获得了数十万的转发量,让许多Java程序员受…...

Yolov5改进: Yolov5-FasterNet网络推理加速
文章目录 1. FasterNet介绍1. 1 FasterNet性能1.2 FasterNet作为Backbone2. 基于C3-Faster实现Yolov5 轻量化2.1 C3-Faster的实现2.2 C3-Faster 在YOLOv5中的使用(1) 在common.py 中添加`C3-Faster`代码(2) 修改yolo.py 中的代码(2) 修改yolov5 yaml文件3. 训练1. FasterNet介绍…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案
这个问题我看其他博主也写了,要么要会员、要么写的乱七八糟。这里我整理一下,把问题说清楚并且给出代码,拿去用就行,照着葫芦画瓢。 问题 在继承QWebEngineView后,重写mousePressEvent或event函数无法捕获鼠标按下事…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!
今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等,设置经线、纬线都以10间隔显示。 2、需要插入背会归线…...

结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...

leetcode_69.x的平方根
题目如下 : 看到题 ,我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历,我们是整数的平方根,所以我们分两…...