当前位置:网站首页>判断链表是否有环
判断链表是否有环
2022-07-30 12:51:00 【qq_25427995】
当链表存在环时,通过直接遍历链表无法知道是否存在环。假设我们可以修改链表结构的话,可以在链表里加入访问的标记,当下一个节点已经被访问过就说明存在环。
方法一、穷举遍历
首先从头节点开始,依次遍历单链表的每一个节点。每遍历到一个新节点,就从头节点重新遍历新节点之前的所有节点,用新节点ID和此节点之前所有节点ID(即重新遍历len-1步)依次作比较。如果发现新节点之前的所有节点当中存在相同节点ID,则说明该节点被遍历过两次,链表有环;如果之前的所有节点当中不存在相同的节点,就继续遍历下一个新节点,继续重复刚才的操作。
例如这样的链表:A->B->C->D->B->C->D, 当遍历到节点D的时候,我们需要比较的是之前的节点A、B、C,不存在相同节点。这时候要遍历的下一个新节点是B,B之前的节点A、B、C、D中恰好也存在B,因此B出现了两次,判断出链表有环。
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
bool detectCycle(ListNode *head) {
ListNode *tem = head,*temp;
int len = 0;
while(tem){
*temp = head;
for(int i=0;i<len;i++)
{
if(temp==tem) return true;
temp = temp->next;
}
len++;
tem = tem->next;
}
return false;
}
时间复杂度为(n^2),空间复杂度为O(1)。
方法二、哈希表/set 缓存
哈希表:首先创建一个以节点ID为键的HashSet集合,用来存储曾经遍历过的节点。然后同样是从头节点开始,依次遍历单链表的每一个节点。每遍历到一个新节点,就用新节点和HashSet集合当中存储的节点作比较,如果发现HashSet当中存在相同节点ID,则说明链表有环,如果HashSet当中不存在相同的节点ID,就把这个新节点ID存入HashSet,之后进入下一节点,继续重复刚才的操作。
set集合:还可以用 set 遍历链表,把节点放入set里,每次访问下个节点时,如果set长度不变,则跳出,说明有环。否则set长度+1,继续遍历。
ListNode *detectCycle(ListNode head) {
set<ListNode node> s;
while(head){
if(s.size()==s.push(head)) return true;
head = head->next();
}
return false;
}
该方法时间复杂度是O(N),空间复杂度上因为需要额外等数量的存储空间,所以空间复杂度是O(n)。
方法三、快慢指针
首先创建两个指针1和2(在java里就是两个对象引用),同时指向这个链表的头节点。然后开始一个大循环,在循环体中,让指针1每次向下移动一个节点,让指针2每次向下移动两个节点,然后比较两个指针指向的节点是否相同。如果相同,则判断出链表有环,如果不同,则继续下一次循环。
例如链表A->B->C->D->B->C->D,两个指针最初都指向节点A,进入第一轮循环,指针1移动到了节点B,指针2移动到了C。第二轮循环,指针1移动到了节点C,指针2移动到了节点B。第三轮循环,指针1移动到了节点D,指针2移动到了节点D,此时两指针指向同一节点,判断出链表有环。
ListNode *detectCycle(ListNode *head) {
ListNode *tem,*temp;
tem = temp = head;
while(tem && temp){
tem = tem->next;
temp = temp->next->next;
if(tem==temp) return true;
}
return false;
}
该方法时间复杂度是O(N),空间复杂度上因为需要额外等数量的存储空间,所以空间复杂度是O(1)。
链表中环的入口节点 - 力扣(LeetCode) (leetcode-cn.com)
扩展z何判断两个单链表是否相交,以及相交点
方法一、直接法
直接判断第一个链表的每个结点是否在第二个链表中,时间复杂度为O(len1*len2),耗时很大。
方法二、利用计数
如果两个链表相交,则两个链表就会有共同的结点;而结点地址又是结点唯一标识。因而判断两个链表中是否存在地址一致的节点,就可以知道是否相交了。可以对第一 个链表的节点地址进行hash排序,建立hash表,然后针对第二个链表的每个节点的地址查询hash表,如果它在hash表中出现,则说明两个链表有共 同的结点。这个方法的时间复杂度为:O(max(len1+len2);但同时还得增加O(len1)的存储空间存储哈希表。这样减少了时间复杂度,增加 了存储空间。
以链表节点地址为值,遍历第一个链表,使用Hash保存所有节点地址值,结束条件为到最后一个节点(无环)或Hash中该地址值已经存在(有环)。
再遍历第二个链表,判断节点地址值是否已经存在于上面创建的Hash表中。
这个方面可以解决题目中的所有情况,时间复杂度为O(m+n),m和n分别是两个链表中节点数量。
方法三、利用有环链表思路
对于两个没有环的链表相交于一节点,则在这个节点之后的所有结点都是两个链表所共有的。如果它们相交,则最后一个结点一定是共有的,则只需要判断最后一个结点是否相同即可。时间复杂度为O(len1+len2)。对于相交的第一个结点,则可求出两个链表的长度,然后用长的减去短的得到一个差值 K,然后让长的链表先遍历K个结点,然后两个链表再开始比较。
参考
原文链接:https://blog.csdn.net/u010983881/article/details/78896293
边栏推荐
- odoo--qweb模板介绍(一)
- [PostgreSQL] - Storage structure and cache shared_buffers
- 58. 最后一个单词的长度
- 关于香港高防IP需要关注的几个问题
- R语言ggpubr包的ggboxplot函数可视化分组箱图、自定义移除可视化图像的特定对象(移除可视化图像轴坐标轴的刻度线标签文本、both x and y axis ticks labels)
- 机器学习——特征选择
- How to migrate the device data connected by RTSP of EasyCVR platform to EasyNVR?
- leetcode207.课程表(判断有向图是否有环)
- 忆联:激活数据要素价值潜能,释放SAS SSD创新红利
- What are the hard-core upgrades and applications that cannot be missed in Greenplum 6.0?
猜你喜欢

MySQL【排序与分页】

Win11打不开exe应用程序怎么办?Win11无法打开exe程序解决方法

Greenplum 6.0有哪些不可错过的硬核升级与应用?

力扣——15. 三数之和

【Kaggle比赛常用trick】K折交叉验证、TTA

MySQL查询性能优化

Using Baidu EasyDL to realize the recognition of the chef's hat of the bright kitchen

腾讯称电竞人才缺口200万;华为鸿蒙3.0正式发布;乐视推行每周工作4天半?...丨黑马头条...

Decoding Redis' most overlooked high CPU and memory usage issues

【语音识别】基于GMM-HMM的语音识别系统
随机推荐
【河北工业大学】考研初试复试资料分享
Hu-cang integrated e-commerce project (1): project background and structure introduction
dolphinscheduler adds hana support
Execution order of select, from, join, on where groupby, etc. in MySQL
JS事件的相关特性以及原理
dolphinscheduler simple task definition and complex cross-node parameter transfer
展厅全息投影所具备的三大应用特点
基于卷积神经网络与双向长短时融合的锂离子电池剩余使用寿命预测
Decoding Redis' most overlooked high CPU and memory usage issues
CMake库搜索函数居然不搜索LD_LIBRARY_PATH
缓存
Markdown 1 - 图文音视频等
ES6 Set与Map是什么,如何使用
JS事件参数对象event
How to migrate the device data connected by RTSP of EasyCVR platform to EasyNVR?
Lake storehouse which electricity (2) of the project: project using technology and version and the environment
[BJDCTF2020]Cookie is so stable-1|SSTI injection
13-GuliMall 基础篇总结
北上广线下活动丨年底最不可错过的技术聚会都齐了
R语言使用方差分析ANOVA比较回归模型的差异、anova函数比较两个模型并报告它们是否存在显著差异(两个模型的数据相同,一个模型使用的预测特征包含另外一个模型的特征)