leetcode OJ 判断单链表中是否有环

来源:互联网 发布:网络层通过什么通信 编辑:程序博客网 时间:2024/05/17 01:05

题目:判断单链表中是否存在环

Binary Tree Preorder Traversal

 


单链表的结构体为:

struct NodeList{    int val;    NodeList *next;    NodeList(int x) : val(x),next(NULL){}};

思路很简单,就是搞两个指针,初始值均指向链表头,但是一个跑的快,一个跑的慢。如果链表中没有环,两个指针不会相遇,如果有环的话,则一定会相遇(慢的被套圈了)。

这里我们定下快指针一次走两步,慢指针一次走一步。由于快指针每次追慢指针一格,快慢指针间最大距离<环长(快指针刚过环入口,慢指针进来了),所以在慢指针第一次走完环长之前,快指针必然能追上它(此处为后面做铺垫)。


判断有否存在环的算法,思路有了很简单:

bool hasCircle(NodeList *head){    NodeList *fast=head;    NodeList *slow=head;    while(fast!=NULL&&fast->!=NULL)    {        fast=fast->next->next;        slow=slow->next;        if(fast==slow) return true;    }    return true;}

看了看大牛写的题目扩展,一般还要求找出环入口的位置,

思路是这样的:


假设相遇时慢指针走了s,则快指针走了2s,两者的差s必然为环长的n倍,即s=nl(l为环长),即如果一个指针S1从链表头出发,另一个指针S2从相遇点出发(两者速度相同),S1走到S2出发点时两者一定会相遇(两者都走了nl),而他们的速度是一样的,说明他们在环入口处其实就相遇了,而且是第一次相遇(就在一起了~~~~),这样我们就能定位到环入口了。


有了思路代码也很简单(环已经存在):

NodeList* findCircleEnter(NodeList* head){    NodeList *fast=head;    NodeList *slow=head;    while(fast!=NULL&&fast->!=NULL)    {        fast=fast->next->next;        slow=slow->next;        if(fast==slow) break;    }    slow=head;    while(slow!=head)    {        slow=slow->next;        fast=fast->next;    }    return slow;}


另外,大牛还引申了“如何判断两个无环单链表是否相交”:运用判断单链表环的想法,将其中一个链表首尾相连,然后判断另一个是否有环,若有环则说明两链表相交。


附上链接:

http://www.cppblog.com/humanchao/archive/2012/11/12/47357.html

0 0
原创粉丝点击