【c数据结构】OJ练习篇 帮你更深层次理解链表!(相交链表、相交链表、环形链表、环形链表之寻找环形入口点、判断链表是否是回文结构、 随机链表的复制)

目录

一. 相交链表

二. 环形链表

三. 环形链表之寻找环形入口点

四. 判断链表是否是回文结构

五. 随机链表的复制


一. 相交链表

最简单粗暴的思路,遍历两个链表,分别寻找是否有相同的对应的结点。

  1. 我们对两个链表的每个对应的节点进行判断比较,如果不相等的话

  2. 那么我们就进行换下一对节点进行判断

但这里存在一个弊端,两条链表可能有一条长,一条短,存在节点数不一样的情况,挨个比较。

举例来说,只是举例来说:

  • 假设一个链表是6个节点,一个是8个节点,那么差值就是8

  • 那么我们让长的那个链表优先走 | 8-6 | 步,走后两个链表长度一致,就能开始进行比较了

  • 解决这个问题很简单--> 遍历计算两个链表长度求差,让长的先走完差值步,使两条链表长度一致。 

于是思路有,步骤有√

  1. 求差求两个链表长度差值
  2. 让长的链表先走差值步
  3.  遍历两个链表,分别对应是否指向相同的结点
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {//1. 遍历两个链表,求他们的长度差//设置两个链表头结点,方便遍历ListNode* l1 = headA;ListNode* l2 = headB;//设置变量存放链表长度,方便求差int sizeA=0,sizeB=0;//遍历计算两条链表长度ingwhile(l1){sizeA++;l1 = l1->next;}while(l2){sizeB++;l2 = l2->next;}//求长度差int gap = abs(sizeA-sizeB);//abs 绝对值函数//2.长链表先走长度差步//由于不知道哪个链表长,先随便定义再判断ListNode* longList = headB;ListNode* shortList = headA;if(sizeA > sizeB){longList = headA;shortList = headB;}//长链表先走while(gap--){longList = longList->next;}//此时的longList和shortList在同一起跑线//3. 遍历两个链表,要么相交,要么不相交while(longList && shortList)//条件是两个链表都不得是空{if(longList == shortList)//找到相同结点,相交{return longList;//反正相同结点,返回long 和short 都一样}//不相同,换下一结点继续比较longList = longList->next;shortList = shortList->next;}return NULL;//循环结束,可见不相交,返回空}

二. 环形链表

类似追击问题,若快指针在追慢指针的时候追到了,说明链表带环

 

如果链表不是带环的,那么快慢指针是绝对不会相遇的
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {//创建快慢指针ListNode* slow = head;ListNode* fast = head;while(fast && fast->next){//慢指针走一步,快指针走两步,相当于快在一步一步追慢slow = slow ->next;fast = fast ->next->next;//相遇,说明带环if(fast == slow){return true;}}return false;
}

三. 环形链表之寻找环形入口点

假设meet为快慢指针相遇点

 

遍历头结点pcur和meet,因为环形,终将相遇
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {//1. 找快慢指针相遇点->说明是环形结点ListNode* slow = head;ListNode* fast = head;while(fast && fast ->next){slow = slow ->next;fast = fast ->next->next;if(fast == slow)//找到相遇点!是环形{//2. 遍历头结点和快慢指针相遇点,每次一步,其相遇点就是环形入环第一个结点ListNode* pcur = head; //定义头结点while(pcur != fast){//但凡是环形,肯定会相遇pcur = pcur ->next;fast = fast ->next;}return pcur;}}return NULL;
}

四. 判断链表是否是回文结构

 

先找中间结点(快慢指针)
再将中间结点之后的链表反转,最后链表左右进行比较看是否相同
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:bool chkPalindrome(ListNode* A) {//1. 找中间结点ListNode* slow = A;ListNode* fast = A;while(fast &&fast->next){slow = slow->next;fast = fast->next->next;}ListNode* mid = slow;//2. 根据中间结点反转后面的链表ListNode* n1 = NULL;//指向空ListNode* n2 = mid;//指向中间结点ListNode* n3 = n2->next;//指向n2的下一个结点while(n2){n2->next = n1;//n2指向其前一个结点(初始是空)n1 = n2;//n1往后走n2 = n3;//n2往后走if(n3)//前提:n3不得为空,n3才能继续往后走n3 = n3->next;//n3往后走}ListNode* right =n1;//n1为我反转链表的头结点//3. 比较原链表和反转链表的结点ListNode* left = A;//原链表头结点while(right)//反转链表的尾结点是指向空的,当其走到空,说明遍历完了{if(left->val != right->val){//有不相等的值,说明不回文return false;}left = left->next;right = right->next;}return true;}
};

五. 随机链表的复制

思路:

原链表上复制并插入复制结点

赋值random

断开链表

/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/
typedef struct Node Node;
//复制链表结点
Node* buynode(int x){Node* newnode = (Node*)malloc(sizeof(Node));newnode->val = x;newnode->next = newnode->random = NULL;return newnode;
}
//将复制的新链表插入原链表
void AddNode(Node* head){Node* pcur = head;//头结点while(pcur){Node* Next = pcur->next;//原链表的下一结点Node* newnode = buynode(pcur->val);//要复制的新结点newnode->next = Next;pcur->next = newnode;pcur = Next;//pcur走到下一结点}}struct Node* copyRandomList(struct Node* head) {if(head == NULL){return NULL;}//1. 原链表上复制结点//此时链表是 node1 -> newcopy1 -> node2 -> newcopy2-> node3..AddNode(head);//2. 赋值randomNode* pcur = head;while(pcur){//循环修改random指针Node* copy = pcur->next;//此时pcur的下一结点即上一步插入的复制结点if(pcur->random != NULL){//因为创建新的节点时,直接让random指向空,现在只需将原链表中random不指向空的进行处理copy->random = pcur->random->next;}pcur = copy->next;//copy下一结点为原链表的下一结点}//3. 断开链表pcur = head;//让pcur回到头结点Node* newhead,*newtail;//为新链表创建头结点和要遍历连接的结点newhead = newtail = pcur->next;//pcur下一结点就是复制的新链表的头结点while(pcur->next->next)//因为有多插入复制的,所以pcur->next->next才是原链表下一结点{pcur = pcur->next->next;//pcur走到原链表下一结点newtail->next = pcur->next;//新链表连接新链表(被复制的)下一结点newtail = newtail->next;//新链表往后走}return newhead;//返回新链表头结点
}

 希望对你有帮助

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

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

相关文章

量化交易----数据透视表----融资融券优惠代码

我们在制定和执行量化策略的过程中,常常需要快速检查目标因子组合的分组下portfolio的超额收益,我们来提供一个快速的方法,可以实现单因子分组,双因子分组和三因子分组 比如拿到一个分析师预测的数据库,和A股市场政策…

python:django项目知识点02——搭建简易授权码核销系统

前言 如标题所述,本篇博客主要围绕快速搭建业务系统展开,旨在:快速、逻辑分明。 适用对象 djangomysql,实现一套授权码核销功能,包含用户登录和授权码核销两个方面内容 业务代码 前述 基础代码已在上篇博客中讲述&…

Vue3:provide-inject实现组件通信

目录 一.作用 1.跨层级通信 2.避免重复声明 3.封装通用服务 二.性质 1.非响应式 2.不可选项 3.高级用法 三.使用 1.爷组件 2.父组件 3.子组件 四.代码 1.爷组件代码 2.父组件代码 3.子组件代码 五.效果 Vue3中的provide-inject机制是用于在组件树中进行依赖注…

01【MATLAB】最小二乘系统辨识

目录 1.系统辨识的定义及其分类 1.1 系统辨识的定义 1.2 系统辨识的分类 2.参数模型 3.系统辨识的步骤 一、最小二乘法(Least Squares Method)一般步骤 二、LSM原理及应用 三、LSM在控制系统建模中的应用 1.系统辨识的定义及其分类 1.1 系统辨识的…

有没有适合初学者的 OpenLayers 项目实战案例推荐?

对于初学者来说,OpenLayers 提供了一系列实用的项目实战案例,可以帮助你快速上手并掌握关键的开发技能。以下是一些推荐的入门项目案例: 1.基础地图显示: 学习如何创建一个简单的地图视图,并加载基础的地图图层&…

19个邮件群发小技巧,最大水平充分利用邮件营销

邮件群发在现代通信中占据着非常重要的位置。无论是在商业环境还是个人生活中,它都有着广泛的应用。无论您是公司的市场推广专家,还是社交团体的筹办者,掌握有效的邮件群发技巧会帮助您更好地传递信息、节约时间和提升工作效率。 确定目标受众…

DK5V100R20S双引脚同步整流芯片12V 2.4A封装SM-7

高性能双引脚同步整流芯片 DK5V100R20S是一款简单高效率的同步整流芯片,只有A,K两个引脚,分别对应肖特基二极管PN管脚。芯片内部集成了100V功率NMOS管,可以大幅降低二极管导通损耗,提高整机效率,取代或替换…

Debian安装mysql遇到的问题解决及yum源配置

文章目录 一、安装mysql遇到的问题解决二、Debain系统mysql8.0的安装以及远程连接三、彻底卸载软件四、Python 操作 mysql五、debian软件源source.list文件格式说明1. 第一部分2. 第二部分3. 第三部分4. 第四部分5. 关于源的混用问题6. 按需修改自己的sources.list7. 更新软件包…

详解运行时安全检测神器:Falco

在当今快速发展的云计算和容器技术时代,安全已成为组织面临的一大挑战。随着云原生应用的普及,传统的安全措施已不足以应对复杂的分布式环境。在这样的背景下,Falco应运而生,成为云原生安全领域的一颗新星。目前在github中,该项目已经拥有了7.3k的star,众…

显示和隐藏图片【JavaScript】

使用 JavaScript 来实现显示和隐藏图片。下面是一个简单的示例&#xff0c;展示如何通过按钮点击来切换图片的可见性。 实现效果: 代码&#xff1a; <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name&…

Sample Packing:长序列 LLM 训练的 Attention 问题及优化

一、背景 之前看过部分 Megatron-LM 的源码&#xff0c;也详细分析过对应的 Dataset 和 DataLoader&#xff0c;想当然的认为在 LLM 预训练时会使用 Document Level 的 Mask&#xff0c;也就是常说的 Sample Packing 技术。最近我们在做长序列训练相关工作时发现并非如此&…

灰狼算法求解函数,MATLAB代码

目录 程序说明 概述 主要功能 关键函数 结论 程序说明 概述 该程序实现了灰狼优化算法&#xff08;GWO&#xff09;&#xff0c;用于求解优化问题。该算法模拟灰狼的捕猎行为&#xff0c;通过种群搜索找到最优解。程序中定义了种群数量、问题维度、变量上下界和适应度函…

全行业商家0退货0退款一键卖全球,淘天助力卖家拓展海外生意!

今年7月中旬&#xff0c;淘宝推出了“大服饰全球包邮计划”&#xff0c;在服饰行业先行先试&#xff0c;带领商家拓展海外市场。计划推出以来&#xff0c;吸引了数十万服饰商家报名参与&#xff0c;包括天猫商家蕉下、淘宝商家JOC、美洋等。有服饰商家怀着试一试的心态报了名&a…

碳课堂|CBAM的制度及核心内容

引言 全球变暖和气候变化是21世纪面临的最严峻挑战之一。为应对这一全球性问题&#xff0c;各国纷纷采取措施&#xff0c;减少温室气体排放&#xff0c;并推动可持续发展。其中&#xff0c;欧盟提出的碳边界调整机制&#xff08;CBAM, Carbon Border Adjustment Mechanism&…

pr视频剪辑、福昕剪辑……四款剪辑视频大比拼

最近入了视频剪辑的坑&#xff0c;我最近在尝试不同的视频剪辑软件&#xff0c;想找到最适合我的那一款。今天&#xff0c;我就来跟大家分享一下我使用福昕视频剪辑、爱拍视频剪辑、Adobe Premiere&#xff08;简称PR&#xff09;和Shotcut这四款软件时的一些体验和感受。希望我…

FPGA_传递参数的方式

FPGA Verilog 调用模块后带有 “ #()” 的含义 最后4个LED闪烁控制模块的例化,它们的源码都是 led_controller.v 模块&#xff0c;但它们的名称不一样,分别为“uut_led_controller_clk12m5 ”&#xff0c;“uut_led_controller_clk25m”&#xff0c;“uut_ledcontroller clk50…

Pandas -----------------------基础知识(二)

dataframe读写数据操作 import pandas as pd# 准备数据(字典) data [[1, 张三, 1999-3-10, 18],[2, 李四, 2002-3-10, 15],[3, 王五, 1990-3-10, 33],[4, 隔壁老王, 1983-3-10, 40] ]df pd.DataFrame(data, columns[id, name, birthday, age]) df写到csv文件中 &#xff0c;…

Azure Pipeline 常用任务记录

各种任务的查询&#xff1a; 任务查询 下载类 1 DownloadPackage1 从 Azure Artifacts 中的包管理源下载包 2 DownloadSecureFile1 下载安全文件&#xff0c;这里的安全文件在Library中上传&#xff0c;默认的位置会传到$(Agent.TempDirectory) 3 DownloadBuildArtifacts1…

shopify主题开发中给产品页设置多个模板

在shopify开发中&#xff0c;有时候商家可能需要为不同的产品去设置自己想要的产品页模板。下面主要教大家如何为产品类型页面设置多个模板&#xff0c;大家只要按照下面几个步骤就可以轻松实现产品的定制化页面&#xff1a; 1、首先在定制器创建产品模板 进入商品自定义页面…

【LangChain系列】实战案例5:用LangChain实现灵活的Agents+RAG,该查时查,不该查时就别查

目前为止&#xff0c;我们实现的RAG练习中&#xff0c;答案都是全部来源于检索到的文本内容。而检索过程可能在某些情况下是不需要的。 如何优化这个过程&#xff0c;让我们的RAG程序在必要时才去检索&#xff0c;不必要时&#xff0c;直接使用大模型原有数据来回答呢&#xf…