【数据结构练习】单链表OJ题(二)

目录

    • 一、相交链表
    • 二、环形链表1
    • 三、环形链表2
    • 四、链表分割
    • 五、复制带随机指针的链表

一、相交链表

题目:
在这里插入图片描述
示例:
在这里插入图片描述
注意:不能根据节点的值来比较是否相交,而是根据节点在内存中是否指向相同的位置。

例如以上图:

链表A:4、1、8、4、5
链表B:5、6、1、8、4、5

链表A和链表B都有节点的值为1,但是它们在内存中指向不同的位置,而值为8的节点(A的第三个节点、B的第四个节点)则在内存中指向相同的位置。

大体思路:链表A和链表B如果相交,那么它们的后几个或者一个节点的位置是一样的。它们的长度不一定一样长,所以要先计算出链表A和链表B的长度,让较长的链表先走长度差的距离,然后再同时走,直到两个链表相交,返回那个开始相交的节点。

计算链表长度:
分别定义一个变量遍历链表,不为空计数器加1往后走,直到循环结束跳出。

如果没有相交返回空:
此时分别遍历两个链表的指针已经走到尾了。假设两个链表有相交,不管是一个还是多个,那么这两个指针肯定是一样的(指相交);如果两个链表不相交,即使是最后的节点也同样不相交,所以就直接返回NULL。

较长的链表先走节点数之差:
用一个变量等于链表长度之差,因为并不知道是A链表长还是B链表长,所以使用绝对值函数abs。先假设是A链表长,B链表短。设置一个条件,如果A链表的长度小于B链表的长度,就反过来。如果假设的是对的,较长的链表先走长度之差的距离。

一起走,直到相交:
两个链表同时走到某个节点相交了,就跳出循环,然后赋给新的头指针,并且返回这个头指针。

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {int len1=0;int len2=0;struct ListNode *cur1=headA;struct ListNode *cur2=headB;//先算出两个链表的节点数while(cur1){len1++;cur1=cur1->next;}while(cur2){len2++;cur2=cur2->next;}//如果没有相加点返回空if(cur1!=cur2){return NULL;}//长的先走节点数之差int k=abs(len1-len2);struct ListNode *longhead=headA;struct ListNode *shorthead=headB;if(len1<len2){longhead=headB;shorthead=headA;}while(k){longhead=longhead->next;k--;}//一起走,直到相交while(longhead!=shorthead){longhead=longhead->next;shorthead=shorthead->next;}struct ListNode *newhead=longhead;return newhead;
}

二、环形链表1

题目:
在这里插入图片描述
使用的是双指针法

定义两个快慢指针fast和slow,从起点出发。先fast一次走两步,slow一次走一步,再判断两个指针是否相同。如果链表有环,那么fast或者fast->next永远不为空,一直在循环里转;如果链表没有环,fast又走得比slow快,所以fast或者fast->next到空就结束。这里fast比slow快一步,即每次距离缩短1步,所以只要有环,fast先在环里转,然后slow随后进环,每次它们的距离缩短1,最终相遇。

bool hasCycle(struct ListNode *head) {struct ListNode *slow=head;struct ListNode *fast=head;while(fast&&fast->next){slow=slow->next;fast=fast->next->next;if(slow==fast){return true;}}return false;
}

三、环形链表2

题目:
在这里插入图片描述
这题与上面的题多增加了一个设定,如果有环,返回的是开始入环的第一个节点。没有环返回空。

那么始入环的第一个节点怎么找呢?其实这里是有关数学计算的。

还是使用两个快慢指针,fast一次走两步,slow一次走一步。如果链表没有环,fast或者fast->next为空,然后返回空指针。如果链表有环,在环的某个位置相遇(注意:fast先入环,可能已经在环里转了n圈了)。假设相遇点与入环点的距离为x,起始点到入环点的距离为L,环的剩下的距离为nC-x(n表示fast已经在环里转了n圈)。

fast从起始点到相遇点的距离为:L+nC+x
slow从起始点到相遇点的距离为:L+x

因为fast一次的步长为slow的两倍

所以:
2(L+x)=L+nC+x
L+x=nC
L=nC-x

根据数学计算转换为:两个指针分别一个从相遇点走,另一个从起始点走,以相同的步长,它们会在入环的第一个节点相遇,然后返回这个相遇点就是入环的第一个节点。

在这里插入图片描述

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode *slow=head;struct ListNode *fast=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(slow==fast){struct ListNode *rid=slow;struct ListNode *mrid=head;while(rid!=mrid){rid=rid->next;mrid=mrid->next;}return rid;}}return NULL;
}

四、链表分割

题目:
在这里插入图片描述
假设一个链表为:

2、3、1、4、2、5

假设x等于3,数据小于的3的节点有:2、1、2
大于等于3的节点有:3、4、5

题目要求将小于x的节点排在其余节点之前,并且不能改变原来的数据顺序。

大体思路:这里我们可以采用分为两个链表的方式。将数据小于x的节点放在一个A链表里,大于等于的放在B链表里。然后把A链表的尾节点与B链表的头节点连接起来。

但是这里要注意一个问题,如果A链表没有节点怎么与B链表连接,这种情况要单独判断,比较麻烦。所以我们可以采用创建哨兵位头节点解决这个问题。

注意:最后B链表的尾节点要指向空指针,同时释放两个哨兵位节点,返回第一个有效节点。
在这里插入图片描述

class Partition {
public:ListNode* partition(ListNode* pHead, int x) {struct ListNode* cur=pHead;struct ListNode* head1, *tail1, *head2, *tail2;head1=tail1=(struct ListNode*)malloc(sizeof(struct ListNode));head2=tail2=(struct ListNode*)malloc(sizeof(struct ListNode));while(cur){if(cur->val<x){tail1->next=cur;tail1=tail1->next;}else{tail2->next=cur;tail2=tail2->next;}cur=cur->next;}tail2->next=NULL;tail1->next=head2->next;struct ListNode* newhead=head1->next;free(head1);free(head2);return newhead;}
};

五、复制带随机指针的链表

题目:
在这里插入图片描述
要拷贝原节点,并且拷贝节点的随机指针也要指向对应的节点,最后还原原链表。

每个拷贝节点都在原节点的后面:
用一个变量cur遍历链表,只要不为空每次进入循环先定义一个变量next记录原链表的下一个位置(cur在原链表的下一个位置,方便一次拷贝完找到),然后开辟一块空间copy为拷贝节点,把原节点的值赋给拷贝节点,再让cur的下一个地址为copy,copy连接next。
在这里插入图片描述
置每个拷贝random:
原链表的每个节点的random指针都有对应的指向,拷贝节点也要有random指针对应的指向,只是拷贝节点的random指针要与原节点的random指针指向保持一致。比如原节点13的random指针指向原节点的7,那么拷贝节点13的random指针则指向拷贝节点的7。

问题是拷贝节点的random指针怎么找到它对应的节点呢?其实上面一步把每个拷贝节点放在原节点的后面有一个好处,方便这一步找到它的random指针。

以拷贝节点13为例:拷贝节点13的random指针,就是它的原节点的random指针所指向的原节点的下一个节点。如果原节点的random指向空,拷贝节点的randon也是指向空。

在这里插入图片描述
拷贝节点解下来,尾插在一起,恢复原链表:
在这里插入图片描述

struct Node* copyRandomList(struct Node* head) {struct Node* cur=head;//复制某个节点到原节点的后面while(cur){struct Node* next=cur->next;struct Node* copy=(struct Node*)malloc(sizeof(struct Node));copy->val=cur->val;cur->next=copy;copy->next=next;cur=next;}cur=head;//处理拷贝节点的random指针指向while(cur){struct Node* copy=cur->next;if(cur->random==NULL){copy->random=NULL;}else{copy->random=cur->random->next;}cur=copy->next;}cur=head;//把拷贝指针连接起来,还原原来的链表struct Node* newhead=NULL;struct Node* tail=NULL;while(cur){struct Node* copy=cur->next;struct Node* next=copy->next;if(tail==NULL){newhead=tail=copy;}else{tail->next=copy;tail=tail->next;}cur->next=next;cur=next;}return newhead;
}

在这里插入图片描述
感谢观看~

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

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

相关文章

SHEIN、OnBuy、FNAC等跨境平台如何搭建自养号环境进行高效测评补单。

SHEIN是一家全球领先的时尚和生活方式在线零售商&#xff0c;通过按需生产的模式赋能供应商共同打造敏捷柔性供应链&#xff0c;从而减少浪费&#xff0c;并向全球消费者提供丰富且具有性价比的时尚产品。目前SHEIN直接服务全球超过150个国家和地区的消费者&#xff0c;并致力于…

n-皇后问题(DFS)

n−皇后问题是指将 n 个皇后放在 nn 的国际象棋棋盘上&#xff0c;使得皇后不能相互攻击到&#xff0c;即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n&#xff0c;请你输出所有的满足条件的棋子摆法。 输入格式 共一行&#xff0c;包含整数 n。 输出…

【C++11】future和async等

C11的future和async等关键字 1.async和future的概念 std::async 和 std::future 是 C11 引入的标准库功能&#xff0c;用于实现异步编程&#xff0c;使得在多线程环境中更容易处理并行任务。它们可以帮助你在不同线程中执行函数&#xff0c;并且能够方便地获取函数的结果。 在…

20230822 Windows上使用find_package引入OpenCV报错

报错信息 打开Cmake项目时&#xff0c;find_package 报错&#xff1a; Found OpenCV Windows Pack but it has no binaries compatible with yourconfiguration.You should manually point CMake variable OpenCV_DIR to your build of OpenCVlibrary.原因 大概率原项目是在 …

三次握手四次挥手之全连接半连接队列

什么是全连接半连接 在 TCP 三次握手的时候&#xff0c;Linux 内核会维护两个队列&#xff0c;分别是&#xff1a; 半连接队列&#xff0c;也称 Listen 队列&#xff1b;全连接队列&#xff0c;也称 accept 队列&#xff1b; 工作原理 每一个socket执行listen时&#xff0c…

arm:day6

实现UART通信&#xff1a; 1.键盘输入一个字符a,串口工具显示b 2.键盘输入一个字符串"nihao",串口工具显示"nihao" uart.h #ifndef __UART4_H__ #define __UART4_H__#include "stm32mp1xx_uart.h" #include "stm32mp1xx_gpio.h" #in…

vr游乐场项目投资方案VR主题游乐馆互动体验

VR文旅景区沉浸互动体验项目是指利用虚拟现实技术在文旅景区中创建沉浸式的互动体验项目。通过虚拟现实技术&#xff0c;游客可以身临其境地体验景区的风景和文化&#xff0c;与虚拟场景中的元素进行互动。 普乐蛙VR设备 普乐蛙VR设备案例分享 这种项目可以为游客带来全新的旅游…

【C++】iota函数 + sort函数实现基于一个数组的多数组对应下标绑定排序

目录 一、iota函数 1. 函数解析 ​① 迭代器类型(补充) ② 头文件 ③ 参数 2. 函数用途与实例 二、sort函数 1、 函数解读 2、实现倒序排列 2.1 greater 与 less 模板参数 2.2 lambda表达式 三、下标绑定排序&#xff08;zip&#xff09; --- 833.字符串中的查找与替换 一、…

ubuntu18.04复现yolo v8环境配置之CUDA与pytorch版本问题以及多CUDA版本安装及切换

最近在复现yolo v8的程序&#xff0c;特记录一下过程 环境&#xff1a;ubuntu18.04ros melodic 小知识&#xff1a;GPU并行计算能力高于CPU—B站UP主说的 Ubuntu可以安装多个版本的CUDA。如果某个程序的Pyorch需要不同版本的CUDA&#xff0c;不必删除之前的CUDA&#xff0c;…

Java快速入门体验

Java快速入门体验 一、环境信息1.1 硬件信息1.2 软件信息 二、Maven安装2.1 Maven介绍2.2 Maven安装包下载2.3 Maven安装2.4 Maven初始化 三、Java安装3.1 JDK下载3.2 JDK安装3.3 JDK初始化 四、开发环境搭建4.1 安装开发工具4.2 关联Maven环境4.2.1 新建JAVA项目4.2.2 Maven与…

DataWhale夏令营第三期-CV赛道-第三次打卡

第三次打卡 使用resnet18训练精度&#xff1a;评分0.74 使用resnet34精度&#xff1a;评分0.74 使用resnet50精度&#xff1a;评分0.21&#xff0c;不知道为什么网络层数高反而准确度下降&#xff0c;猜测层数多丢失了一些特征信息。

2023年国赛 高教社杯数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…

如何理解原假设和备择假设?

原假设H0&#xff1a;一般是想要推翻的结论&#xff0c;如指标没有变化&#xff0c;实验组和对照组的该结果指标没有差异等。 备择假设H1&#xff1a;一般是想要证明的结论&#xff0c;如实验组的指标是显著提升的&#xff0c;指标提升10%等。 反证法的思想&#xff1a;因为假…

CDH集群离线配置python3环境,并安装pyhive、impyla、pyspark

背景&#xff1a; 项目需要对数仓千万级数据进行分析、算法建模。因数据安全&#xff0c;数据无法大批量导出&#xff0c;需在集群内进行分析建模&#xff0c;但CDH集群未安装python3 环境&#xff0c;需在无网情况下离线配置python3环境及一系列第三方库。 采取策略&#xf…

【UniApp开发小程序】私聊功能uniapp界面实现 (买家、卖家 沟通商品信息)【后端基于若依管理系统开发】

文章目录 效果显示WebSocket连接使用全局变量WebSocket连接细节 最近和自己聊天的用户信息界面效果界面代码最近的聊天内容太长日期时间显示未读消息数量显示 私聊界面界面展示代码实现英文长串不换行问题聊天区域自动滑动到底部键盘呼出&#xff0c;聊天区域收缩&#xff0c;聊…

报错:1 字节的 UTF-8 序列的字节 1 无效。

这里我的问题出现在BookMapper.xml中 java.lang.IllegalStateException: Failed to load ApplicationContextat org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)at org.spring…

Hbase--技术文档--单机docker基础安装(非高可用)

环境准备-docker 配置Linux服务器华为云耀云服务器之docker安装&#xff0c;以及环境变量安装 java &#xff08;虚拟机一样适用&#xff09;_docker配置java环境变量_一单成的博客-CSDN博客 说明&#xff1a; 本文章安装方式为学习使用的单体hbase项目。主要是学习&#xff…

Unity之用Transform 数组加多个空物体-->简单地控制物体按照指定路线自动行驶

文章目录 **原理解释**&#xff1a;**带注释的代码**&#xff1a;实际运用 当你需要实现物体按照指定路线行驶时&#xff0c;你可以通过以下步骤来实现&#xff1a; 原理解释&#xff1a; 路径点&#xff1a;你需要定义一系列路径点&#xff0c;这些点将构成物体行驶的路线。每…

双指针算法总结

双指针算法大致有以下几个类型 对撞指针&#xff1a;一般用来处理两数和问题快慢指针&#xff1a; 一般在链表中用的比较多&#xff0c;如求链表中间结点&#xff0c;链表是否有环等&#xff0c;当然一些非链表题也会用到相关的思想区间划分&#xff1a; 将数组分成两个不同性质…

next.js报错点

next.js报错点 1.类型“{ children: ReactNode; }”与类型“IntrinsicAttributes”不具有相同的属性。2. 不能将类型“void[]”分配给类型“ReactNode”&#xff1f;3.useRouter only works in Client Components. Add the "use client" directive at the top of the…