Linked List Cycle II (Java)

来源:互联网 发布:工作室源码 编辑:程序博客网 时间:2024/05/17 07:32

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

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

先用一个指针走一步,另一个指针走两步的方法判断是否存在回路,如果存在,则将其中一个指针指回头结点,然后两个指针一步一步往下走,走到相遇的地方,就是指针环路所在节点。

这个问题就好像是追及问题:


两个小人都从A地出发,一个走的速度是另一个的两倍,走的快的人在跑道上绕了n圈后和走的慢的在B地相遇(跑道长度为k),此时可以列出等式:vt + nk = 2vt (nk是速度快的小人多走的路程),那么可得vt = nk,由于慢的小人从A到B总共走了vt,所以可得 l1 + l2 = nk。 本题问的是环路所在节点,即图中红色部分,所以接着推导上式: l1 + l2 = (n - 1)k + k 即 l1 = (n - 1)k + (k - l2)。 k - l2 即为从B点绕跑道逆时针跑到红点的距离,那么可得出一个指针从A点跑,另一个指针从B点跑,此时他们用一样的速度vt,总能在红点处相遇。

Source

/** * 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 || head.next == null) return null;        boolean flag = false;    ListNode p = head, q = head;    while(q != null && q.next != null){    p = p.next;    q = q.next.next;    if(p == q){    flag = true;    p = head;    break;    }    }    if(flag == false) return null;    else{    while(p != q){    p = p.next;    q = q.next;    }    return q;    }            }}


Test

    public static void main(String[] args){    ListNode a = new ListNode(1);    a.next = new ListNode(4);    a.next.next = new ListNode(3);    a.next.next.next = new ListNode(2);    ListNode b = a.next.next.next;    b.next = a.next;    System.out.println(new Solution().detectCycle(a).val);    }


0 0
原创粉丝点击