Linked List Cycle -- LeetCode

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

                原题链接:  http://oj.leetcode.com/problems/linked-list-cycle/  
这道题是cc150里面的题目,算是链表里面比较经典的题目。
我们先讲一下比较直接容易想到的方法,就是用一个hashset,然后把扫过的结点放入hashset中,如果出现重复则返回true。想法比较简单,也很好实现,这里就不放代码了,有兴趣的朋友可以写写。
下面我们来考虑如何不用额外空间来判断是否有cycle,用到的方法很典型,就是那种walker-runner的方法,基本想法就是维护两个指针,一个走的快,一个走得慢,当一个走到链表尾或者两个相见的时候,能得到某个想要的结点,比如相遇点,中点等等。
介绍完方法,剩下的主要就是数学了,假设两个指针walker和runner,walker一倍速移动,runner两倍速移动。有一个链表,假设他在cycle开始前有a个结点,cycle长度是c,而我们相遇的点在cycle开始后b个结点。那么想要两个指针相遇,意味着要满足以下条件:(1) a+b+mc=s; (2) a+b+nc=2s; 其中s是指针走过的步数,m和n是两个常数。这里面还有一个隐含的条件,就是s必须大于等于a,否则还没走到cycle里面,两个指针不可能相遇。假设k是最小的整数使得a<=kc,也就是说(3) a<=kc<=a+c。接下来我们取m=0, n=k,用(2)-(1)可以得到s=kc以及a+b=kc。由此我们可以知道,只要取b=kc-a(由(3)可以知道b不会超过c),那么(1)和(2)便可以同时满足,使得两个指针相遇在离cycle起始点b的结点上。
因为s=kc<=a+c=n,其中n是链表的长度,所以走过的步数小于等于n,时间复杂度是O(n)。并且不需要额外空间,空间复杂度O(1)。代码如下:
public boolean hasCycle(ListNode head) {    if(head == null)        return false;    ListNode walker = head;    ListNode runner = head;    while(runner!=null && runner.next!=null)    {        walker = walker.next;        runner = runner.next.next;        if(walker == runner)            return true;    }    return false;}
这道题是链表中比较有意思的题目,基于这个方法,我们不仅可以判断链表中有没有cycle,还可以确定cycle的位置,有兴趣的朋友可以看看 Linked List Cycle II
           

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值