环形链表 II

题解:hashset(没有达到进阶的要求)

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> set = new HashSet<>();
        ListNode node = head;
        while(node!=null){
            if(set.contains(node)) return node;
            else set.add(node);
            node=node.next;
        }
        return null;
    }
}

题解:双指针

一个慢指针l和一个快指针r同时走,慢指针l一次走1步,快指针r一次走2步。当快慢指针相遇时,让另一个指针l0从头出发和慢指针l同时移动且步长都是1,当l0和l相等时就找到了入口节点。
证明思路:https://juejin.im/post/5e64a20ff265da570a5d5633#heading-2

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        if(head==null) return null;
        ListNode l=head,r=head,l0=head;
        while(true){
            l=l.next;
            r=r.next==null? null:r.next.next;
            if(l==r&&l!=null){
                while(l!=l0){
                    l=l.next;
                    l0=l0.next;
                }
                return l;
            }
            if(r==null){
                return null;
            }
        }

    }
}

参考剑值offer代码

分为两部分:
1、先计算出环内节点数目n
2、快指针先走n步,之后慢指针和快指针同时走。当它们相遇就是入口

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode h = head;
        int goFirst = numCycle(head);
        if(goFirst == 0) return null;
        ListNode pFast = head,pSlow = head;
        //快指针先走环内节点指针数
        for(int i=0;i<goFirst;i++){
            pFast = pFast == null? null : pFast.next;
        }
       // int index = 0;
        while(pFast != pSlow){
            pSlow = pSlow == null? null:pSlow.next;
            pFast = pFast == null? null:pFast.next;
        }
        return pFast;

        
    }

    //判断环内节点数目
    public int numCycle(ListNode head){
        ListNode pSlow = head,pFast = head;
        while(pFast != null){
            pSlow = pSlow == null ? null : pSlow.next;
            pFast = pFast.next == null ? null : pFast.next.next;
            if(pFast == pSlow) break;
        }
        if(pFast == null) return 0;//无环
        ListNode pFastNext = pFast.next;
        int cnt = 1;
        while(pFast != pFastNext){
            cnt++;
            pFastNext = pFastNext.next;
        }
        return cnt;
    }
}

posted @ 2020-07-18 09:31  浅滩浅  阅读(182)  评论(0编辑  收藏  举报