Linked List Cycle

本文介绍两种链表中是否存在循环的检测方法:一种是通过快慢指针的方式进行判断,另一种是采用双指针遍历的方法。前者利用快慢指针速度差来检测循环,后者通过比较内外层指针移动距离来确定。

https://oj.leetcode.com/problems/linked-list-cycle/

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

 public boolean hasCycle(ListNode head)


为了假装我不是事先知道解的。我先给一个很直观的O(N^2)的算法吧。给一个tmp指针,做两重循环,第一个外层循环tmp每次都往下走,第二个循环里设一个tmp_2指针,从头走碰到tmp停。统计tmp走的步数和tmp_2走的步数,如果不等则是循环。或者tmp走到空指针则不是循环。

    public boolean hasCycle(ListNode head) {
        ListNode tmp = head;
        int ctr = 0;
        while(tmp != null){
            int ctr_2 = 0;
            ListNode tmp_2 = head;
            while(tmp_2 != tmp){
                tmp_2 = tmp_2.next;
                ctr_2++;
            }
            if(ctr_2 != ctr)
                return true;
            ctr++;
            tmp = tmp.next;
        }
        return false;
    }

大家不用试了,这代码在某个大数据的时候TLE,因为这一题oj估计只能接受ON的做法。

O(N)的做法我相信很多人应该都懂了,但我还是说一下,快慢指针,快指针每次走两步,慢指针每次走一步。当慢指针最终遇见了快指针,则表示true,否则快指针先行走到了null,那表示false。给出代码如下:

    public boolean hasCycle(ListNode head) {
        ListNode slow = head, fast = head;
        while(slow != null && fast != null){
            slow = slow.next;
            fast = fast.next;
            fast = fast != null ? fast.next : fast;
            if(fast != null && fast == slow)
                return true;
        }
        return false;
    }
当然还有另一个傻一点的O(N)的做法,哈希表记录走过的节点。当遇到重复的便是循环,否则不是,这做法太直观,我就不写了,肯定能过的。。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值