链表19:有环单链表相交判断
来源:互联网 发布:穿越火线自动开枪源码 编辑:程序博客网 时间:2024/06/05 02:57
题目:如何判断两个有环单链表是否相交?相交的话返回第一个相交的节点,不相交的话返回空。如果两个链表长度分别为N和M,请做到时间复杂度O(N+M),额外空间复杂度O(1)。给定两个链表的头结点head1和head2(注意,另外两个参数adjust0和adjust1用于调整数据,与本题求解无关)。请返回一个bool值代表它们是否相交。
思路:这里已知给定的是两个有环的单链表,要判断这两个有环的单链表是否相交
如何求出环的第一个结点?
方法一:使用剑指offer上面的逻辑:先pslow,pfast遍历得到重合点meetingNode,然后pslow再绕一圈计算出环中的结点数目nodesNumberOfLoop,然后再从头结点开始,p1先走nodesNumberOfLoop步,当p1,p2再次重合的位置就是入口结点—较为复杂。
方法二:使用视频中的逻辑:先pslow,pfast遍历得到重合点meetingNode,然后新的指针p从头结点head开始向下遍历,pslow依然向下遍历,当两者重合时的结点就是入口结点—较为方便,不需要计算环内的结点数目,可以用数学方法证明正确性。--之后改用方法2
对于无环链表判断相交较为简单:先求出两个链表的长度length1,length2,diff=length1,length2,长的链表先走diff步,然后一起走逐个结点进行比较。
对于有环单链表判断相交:
①先求出两条链表的入环结点p1,p2
②判断p1与p2是否相同
(1)如果相同,说明两条链表在入环之前已经相交,此时就相当于是对两条从head到入环结点的链表判断相交性。--判断两条无环链表是否相交
(2)如果不相同,说明在入环之前没有相交,则要判断在环中是否相交(理解,如果环中相交,即从某个meetingNode结点相交,那么之后的所有结点都相交,而由于之后的结点都是环,所以如果在环内相交那么这两个环必定完全重合),于是只要从某个入环结点p1开始遍历这个环每个结点都与p2进行比较,如果相等说明相交,如果绕完一圈都不等那么说明不想交。
//已知链表是有环的链表,判断有环链表的第一个交点,有两种情况:入环结点相同;入环结点不相同;返回第一个交点;题目要求是返回boolean值,但是通用的还是返回第一个相交的结点,所以以下代码的核心是public ListNode returnFirstIntersectionNode(ListNode head1, ListNode head2, int adjust0, int adjust1)方法,只是为了返回boolean而对他进行了一个包装。public class ChkIntersection { public boolean chkInter(ListNode head1, ListNode head2, int adjust0, int adjust1) { ListNode firstIntersectionNode=this.returnFirstIntersectionNode(head1,head2,adjust0,adjust1); return firstIntersectionNode==null ? false:true;}//判断两个有环链表是否相交,如果相交返回第一个相交结点,如果不想交返回null public ListNode returnFirstIntersectionNode(ListNode head1, ListNode head2, int adjust0, int adjust1) { //先得到两条链表的入环结点 ListNode entryNodeOfLoop1=this.entryNodeOfLoop(head1); ListNode entryNodeOfLoop2=this.entryNodeOfLoop(head2); //比较两个入环结点是否相同 if(entryNodeOfLoop1==entryNodeOfLoop2){ //入环结点相同,则在该结点之前的无环链表上面判断有无相同结点 //先求出链表从head到入环结点的长度 int length1=this.listLength(head1,entryNodeOfLoop1); int length2=this.listLength(head1,entryNodeOfLoop2); ListNode longNode=null; ListNode shortNode=null; int diff=0; if(length1<length2){ longNode=head2; shortNode=head1; diff=length2-length1; }else{ longNode=head1; shortNode=head2; diff=length1-length2; } //长链表先走diff步 for(int i=0;i<diff;i++){ longNode=longNode.next; } //一起移动遍历比较 while(longNode!=entryNodeOfLoop1){ if(longNode==shortNode) return longNode; longNode=longNode.next; shortNode=shortNode.next; } return entryNodeOfLoop1; }else{ //入环结点不同,要判断在环中是否相交,即两个链的环是否完全重合 //先将链表1的入环结点记住 ListNode p=entryNodeOfLoop1; p=p.next; while(p!=entryNodeOfLoop1){ if(p==entryNodeOfLoop2) return p; p=p.next; } return null; } } //已知一个链表是有环链表,得到这个链表环的入环结点 public ListNode entryNodeOfLoop(ListNode head){ //定义两个指针 ListNode pfast=head; ListNode pslow=head; //初始时pfast和pslow重合,先走一步再判断 pslow=pslow.next; pfast=pfast.next.next; while(pfast!=pslow){ pslow=pslow.next; pfast=pfast.next.next; } //pslow,pfast必然会重合 ListNode meetingNode=pslow; //根据数学规律得到入环结点 ListNode p=head; while(p!=pslow){ p=p.next; pslow=pslow.next; } return p; } //求出链表从head到tail的长度 public int listLength(ListNode head,ListNode tail){ int length=1; while(head!=tail){ head=head.next; length++; } return length; }}
- 链表19:有环单链表相交判断
- 有环单链表相交判断、单链表相交判断
- 有环单链表相交判断练习
- 链表20:单链表相交判断
- 判断相交
- 【链表】判断两个单链表是否相交
- 2.2 链表-判断两个链表是否相交并判断相交点
- 数据结构与算法分析笔记与总结(java实现)--链表18:有环单链表判断是否相交问题
- 数据结构与算法分析笔记与总结(java实现)--链表19:判断单链表是否相交问题
- 判断线段相交
- 判断线段相交程序
- 判断俩个链表是否相交
- 判断俩链表是否相交
- 判断线段相交
- 怎样判断线段相交
- JS 判断直线相交
- 矩阵相交判断
- 判断俩个链表是否相交
- 链表18:无环单链表判相交
- Educational Codeforces Round 20 C || Codeforces803C Maximal GCD (水题)
- ASP.NET Highcharts图表(1)-环境配置及第一个实例
- 1050. 螺旋矩阵(25)
- MySQL重置密码
- 链表19:有环单链表相交判断
- UVA 133
- linux redis安装
- 第3章、Lift中的表单处理
- poj 1611 The Suspects
- pycharm注册码
- 文章标题
- Hibernate 5.2.10 Unknow Entity exception
- Android Studio 添加和删除 Library Module