首页 > 其他 > 详细

Linked List Cycle II

时间:2015-02-03 22:41:44      阅读:314      评论:0      收藏:0      [点我收藏+]

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

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?

解题思路:

这是个比较复杂的题目,用快慢指针的方法,可以比较容易的得到链表是否有环,但是他俩第一次相遇的node,并不一定是环开始的节点。那么,如何求解?

技术分享

考虑上面的链表,环前的长度为X,环长Y,fast和slow相遇时,已经在环里走了K。假设这时fast绕了m圈,slow绕了n圈,走了T个回合。于是有,

fast:2T=X+Y*M+K

slow:T = X+Y*N+K

消除T,2X+2YN+2K = X+YM+K,于是,X+K=(M-2N)*Y。

这时一个重要的等式,说明X和K相加,必然等于Y的正数倍。也就是说,fast和slow在K相遇时,再一步一步的走X步,肯定回到环的起点了。当然,这时可能只绕了一圈,也可能绕了很多圈(X很长时)。

于是,我们只要仿照判断是否有环的方法,循环直到fast和slow相遇。然后将fast放到head,fast一步一步走X步,到了环的起点,slow也一定到环的起点了。

/**
 * 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 fastNode = head;
        ListNode slowNode = head;
        
        do{
            fastNode = fastNode.next;
            if(fastNode == null){
                return null;
            }else{
                fastNode = fastNode.next;
            }
            slowNode = slowNode.next;
        }while(fastNode != slowNode && fastNode != null);
        
        if(fastNode == null){
            return null;
        }
        
        fastNode = head;
        while(fastNode != slowNode){
            fastNode = fastNode.next;
            slowNode = slowNode.next;
        }
        
        return fastNode;
    }
}

这是一个根据网友总结写出的算法,参考了以下几个页面。

http://fisherlei.blogspot.jp/2013/11/leetcode-linked-list-cycle-ii-solution.html

http://www.cnblogs.com/hiddenfox/p/3408931.html

Linked List Cycle II

原文:http://www.cnblogs.com/NickyYe/p/4271128.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!