标签:
判断链表是否有环方法——快慢指针
一、 问:如何判断是否有环?
答:如果有两个头结点指针,一个走的快,一个走的慢,那么若干步以后,快的指针总会超过慢的指针一圈。
设置两个指针(fast,slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行头到尾部为NULL,则为无环链表)。
#include <stdio.h> typedef struct ListNode { int val; ListNode *next; }; //判断链表是否有环(C++实现) bool isloop(ListNode *pHead) { ListNode *fast=pHead; ListNode *slow=pHead; //链表长度为奇数,则fast->next为空,否则,fast为空 while(fast!=NULL&&(fast->next!=NULL)) { fast=fast->next->next; slow=slow->next; //如果有环,则两个指针在环中某一点相遇 if(fast==slow) { break; } } if(fast==NULL||fast->next==NULL) return false; else return true; }
附其他方法:
法1,遍历链表。
将遍历过的节点放在一个hash表中。如果一个节点已经存在hash表中,说明链表有环。时间复杂度O(n),空间复杂度O(n)。
法2,反转链表。
二、计算环的长度
//计算环的长度:从第一次相遇开始计数,到第二次相遇,走的长度即为环的长度 int len_loop(ListNode *pHead) { if(isloop(pHead)==false) return 0; ListNode *fast=pHead; ListNode *slow=pHead; int len=0; bool begin=false; bool again=false; while(fast->next!=NULL&&fast!=NULL) { fast=fast->next->next; slow=slow->next; //超一圈后开始计数 if(fast==slow&&(again==false)) { begin=true; again=true; } //超过两圈停止计数,跳出循环 if(fast==slow&&(again==true)) break; //计数 if(begin==true) ++len; } return len; }
三、问:如何判断环的入口点?
答:碰撞点p到连接点的距离=头指针到连接点的距离,所以,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。
为什么呢?需要一个简单的计算过程:
(1)当fast与slow相遇时,show肯定没有走完链表,而fast已经在还里走了n(n>= 1)圈。假设slow走了s步,那么fast走了2s步。fast的步数还等于s走的加上环里转的n圈,所以有:
2s = s + nr。因此,s = nr。
(2)设整个链表长为L,入口据相遇点X,起点到入口的距离为a。因为slow指针并没有走完一圈,所以:
a + x = s,带入第一步的结果,有:a + x =nr = (n-1)r + r = (n-1)r + L - a;即:
a = (n-1)r + L -a -x;
这说明:从头结点到入口的距离,等于转了(n-1)圈以后,相遇点到入口的距离。因此,我们可以在链表头、相遇点各设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。
//计算环的入口结点 Node* findLoopEntrance(ListNode *pHead) { ListNode *fast=pHead; ListNode *slow=pHead; while(fast->next!=NULL&&fast!=NULL) { fast=fast->next->next; slow=slow->next; //到达相遇点 if(fast==slow) { break; } } if(fast==NULL||fast->next==NULL) return NULL; slow=pHead;//slow指针从头结点开始遍历 while(slow!=fast) { slow=slow->next; fast=fast->next; } return slow; }附:
如何判断两个链表(不带环)是否相交?将其中的一个链表首尾相连,然后判断另一个链表是否带环即可,而检测出来的依赖环入口即为相交的第一个点。
标签:
原文地址:http://blog.csdn.net/xiaominkong123/article/details/51354248