2-5 求有环链表的环入口节点(证明及代码)
来源:互联网 发布:机柜网络模块接线图 编辑:程序博客网 时间:2024/05/01 15:38
【链表】
Q:Given a circular linked list, implement an algorithm which returns node at the begin-ning of the loop
DEFINITION
Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an
earlier node, so as to make a loop in the linked list
EXAMPLE
Input: A -> B -> C -> D -> E -> C [the same C as earlier]
Output: C
题目:写一个算法求出有环单链表中环的起始点。
举例:
输入:A -> B -> C -> D -> E -> C
输出:C(环的入口节点)
解答:
针对这个问题,一个前置问题是:判断一个链表是否有环?这个问题有快慢指针法、反转链表法、hash法等。
如果我们已知一个链表有环结构存在,我们如何找出环的入口节点呢?
同样可以使用快慢指针的方法,快指针fast每次走2步,慢指针slow每次走一步,当fast和slow相遇时,我们确定了单向链表有环路。接下来,让fast回到链表的头部,重新走,但这次让fast和slow以同样的速度走,每次走1步。那么当fast和slow再次相遇的时候,就是环路的入口了。为什么???
证明:在fast和slow第一次相遇的时,假定slow走了n步,环路的入口是在p步,那么:
slow走的路径: p+c = n; c为fast和slow相交点 距离环路入口的距离
fast走的路径: p+c+k*L = 2*n; L为环路的周长,k是整数。因为fast比slow多走的路就是它多绕了几个圈。
显然,如果从p+c点开始,slow再走n步的话,还可以回到p+c这个点。
同时,fast从头开始走,步长为1,经过n步,也会达到p+c这点。
显然,在这个过程中fast和slow只有前p步骤走的路径不同。所以当p1和p2再次重合的时候,必然是在链表的环路入口点上。
有了思路以后,我们可以编码如下(C代码):
NODE* find_loop(NODE* list){ if(list==NULL) return NULL; NODE *fast=list,*slow=list; while(fast->next!=NULL){ fast=fast->next->next; slow=slow->next; if(fast==slow) break; } if(fast->next==NULL)//如果fast走到尽头了,说明没有环结构存在 return NULL; slow=list; while(fast!=slow){//再次相遇时,在环入口处 fast=fast->next; slow=slow->next; } return fast;}
JAVA参考代码:
LinkedListNode FindBeginning(LinkedListNode head) { LinkedListNode n1 = head; LinkedListNode n2 = head; // Find meeting point while (n2.next != null) { n1 = n1.next; n2 = n2.next.next; if (n1 == n2) { break; } } // Error check - there is no meeting point, and therefore no loop if (n2.next == null) { return null; } /* Move n1 to Head. Keep n2 at Meeting Point. Each are k steps /* from the Loop Start. If they move at the same pace, they must * meet at Loop Start. */ n1 = head; while (n1 != n2) { n1 = n1.next; n2 = n2.next; } // Now n2 points to the start of the loop. return n2; }
作者:Viidiot 微信公众号:linux-code
- 2-5 求有环链表的环入口节点(证明及代码)
- 2-5 求有环链表的环入口节点(证明及代码)
- 单链表的环的入口点一个小证明
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 链表中环的入口节点
- 判断链表是否有环及找到环的入口节点
- 56 - 链表中环的入口节点
- 找出有环链表中环的入口节点
- Python :链表中环的入口节点
- Hadoop搭建
- IT农民工如何来美国工作
- 重叠分组
- ssd动态_nand flash
- 数组数组-最长上升子序列
- 2-5 求有环链表的环入口节点(证明及代码)
- CI(2) views
- zoj 3702 Gibonacci number
- 寻找若干个字符串的最长公共前缀 Longest Common Prefix
- Android开发工程师已难找工作
- POJ 1220 (两种任意进制之间的转换(大数),java的BigInteger)
- linux_source_0_11
- struts.xml配置文件中的action的各项默认值
- 关于submit和button在javaScript中的区别