【数据结构刷题集】链表经典习题
😽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介绍…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
