【Leetcode】142.Linked List Cycle II

Question:

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Note: Do not modify the linked list.

Tips:

给定一个链表,如果链表中有环,返回环开始的结点。如果链表无环 返回null。

思路:

之前141题(链接),判断链表中是否有环,返回布尔类型的变量。本题还需要返回环开始的结点。解决过程分为以下几步。

(1)设置两个速度不同的指针,fast与slow。fast的速度是slow的二倍。

fast = fast.next.next;
slow = slow.next;

当两个指针相遇,证明链表存在结点,否则,fast指针先遇到null证明链表内无环。

(2)在两个指针相遇处切开,则变成了求两个单链表第一个公共结点的问题160(链接)。

slow路程:S1=L+a;(L链表无环部分长度,a为slow指针走过的环内的弧长)

fast路程:S2=L+a+n*k;(n表示环内结点长度,k表示 fast指针走过的环的圈数)

路程=速度*时间。slow的速度*2=fast的速度。相遇代表时间相等。则S1*2=S2。

2(L+a)=L+a+n*k; ==> L+a=n*k

          ==> L=n*k-a;

从上面的分析可以看出,链表中,不在环内的长度L=环的长度n - slow走过的弧长。

这时,新建一个指针,从head开始向后移动,相遇处的指针继续后移,当两个指针再次相遇,则该节点是环开始的第一个结点。

代码:

public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        ListNode meet = null;
        while (fast != null) {
            if (fast.next != null) {
                fast = fast.next;
                if (fast.next != null) {
                    fast = fast.next;
                    slow = slow.next;
                    if (fast == slow) {
                        //fast与slow相遇
                        meet = slow;
                        break;
                    }
                } else
                    return null;
            } else
                return null;
        }
        ListNode haha = head;
        //循环结束,两个指针均指向环开始的结点。
        while (haha != meet) {
            haha = haha.next;
            meet = meet.next;
        }

        return meet;
    }

测试代码:

public static void main(String[] args) {
        ListNode head1 = new ListNode(1);
        ListNode head2 = new ListNode(2);
        ListNode head3 = new ListNode(3);
        ListNode head4 = new ListNode(4);
        ListNode head5 = new ListNode(5);
        ListNode head6 = new ListNode(6);
        head1.next = head2;
        head2.next = head3;
        head3.next = head4;
        head4.next = head5;
        head5.next = head6;
        head6.next = head3;
        L142LinkedListCycleII l142 = new L142LinkedListCycleII();
        ListNode head = l142.detectCycle(head1);
        if(head!=null){
            System.out.println(head.val);
        }else{
            System.out.println("Null");
        }
        
    }

 

posted @ 2018-02-28 23:14  于淼  阅读(131)  评论(0编辑  收藏  举报