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

2 篇文章 0 订阅
2 篇文章 0 订阅

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

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值