找带环单向链表的环入口
来源:互联网 发布:域名和空间费用 编辑:程序博客网 时间:2024/06/05 09:15
题目:一个链表中包含环,请找出该链表的环的入口结点。
这是一个在面笔试中问烂了的问题,虽然以前也做过,也知道怎么做,但是总是想推导出具体的数学公式,这样才具有 说服力,今天又重新温习了一下,做了一下数学公式的推导,然后做一下总结;
1、做此类题首先得判断单链表 是否有环,当然这个题目已经告诉我们是有环的链表啦。
判断有环的方法就是用两个快慢指针p1、p2,p2的速度为P1的两倍,两个指针同时从链表的头结点开始出发,当两个结点再一次相遇的时,说明此链表有环。
2、光判断有环还不够,下一步就是要找到环的入口,这一步的推导相对麻烦一些。
且看下图
从图中可以看出,直线部分的长度为L1,环的长度为L2,入口点到第一次相交点的长度为a。
因为p2的速度是p1的两倍,所以p2肯定是先到达环里面,当p1和p2再环内相遇的时候,p2走过的距离为L1+n*L2+a; 而p1走过的距离为L1+a;写到这里很多人可能会迷惑,为什么p1所走的距离不是L1+m*L2+a呢(m<n)。是这样的,当两个指针在环内第一次相遇的时候p1在环内走过的距离肯定不会超过环的长度。因为当p1刚刚进入环的时候,如果p1和p2没有相遇,那么p1和p2的最大距离为L2-1,这一点相信大家都能明白,而p2的速度为p1的两倍,所以p1最多走到环的一半的时候p2一定能追上p1。
所以可以列出下面的数学式子
从上面的式子可以看出,L1+a的长度为L2的n倍,也就是说,可以先让一个指针从入口结点先走a步(此时恰好是上面所说的交点位置),然后另一个指针从链表的头结点以相同的速度走,当两个指针再次相遇的时候,相遇结点一定是环的入口结点
java代码实现如下
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}*/public class Solution { ListNode EntryNodeOfLoop(ListNode pHead){ if(pHead == null || pHead.next == null) return null; ListNode p1 = pHead; ListNode p2 = pHead; while(p2 != null && p2.next != null ){ p1 = p1.next; p2 = p2.next.next; if(p1 == p2){ p2 = pHead; while(p1 != p2){ p1 = p1.next; p2 = p2.next; } if(p1 == p2) return p1; } } return null; }}
- 找带环单向链表的环入口
- 找出带环单向链表的环入口(交点)
- 找出带环单向链表的环入口(交点)
- 找出带环单向链表的环入口(交点)
- 找出带环单向链表的环入口(交点)
- 找出带环单向链表的环入口(交点)
- 【C语言】找带环单链表的环入口
- 判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- -判断链表是否带环?若带环求环的长度?若带环求环的入口点
- 剑指offer--判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- 判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- 判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- 链表--判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- 判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- 判断链表是否带环,若带环求环的长度,若带环求环的入口点
- 判断链表是否带环?若带环求环的长度?若带环求环的入口点?
- 判断链表是否带环?若带环求环的长度?求环的入口点?
- 判断链表是否带环,以及环的入口
- 利用python Pandas进行数据预处理
- 操作系统常见面试问题
- 我的第一只Python爬虫
- linux命令:cat(常用方法详解)
- C++第四次作业
- 找带环单向链表的环入口
- 设计模式-代理模式
- 快速排序
- 从头来过 四月盛夏 不忘初心
- 《Java编程思想》学习记录
- Unity3D 场景渲染到Cubemap 插件
- 通过jQuery Ajax使用FormData对象上传文件
- Final关键字
- Java学习笔记代码