我们来自五湖四海,不为别的,只因有共同的爱好,为中国互联网发展出一分力!

[LeetCode]Linked List Cycle II解法学习

2014年07月03日17:38 阅读: 19995 次
问题描述如下:
 
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?
 
 
 
从问题来看,如果可以充分利用额外空间的话,这个题目是不难的,然而题目提出了一个要求,能否在不使用任何额外空间的情况下解决这个问题。
 
通过反复思考,我觉得这题类似于追击问题,可以用一个快速遍历指针和一个慢速遍历指针对这个链表进行遍历,如果存在环,那么这个快速指针肯定会在环中某一处追到这个慢指针。尽管有这样的想法,但是在判断出了是否有环之后,该如何进一步获取环的起点呢?个人能力有限,之前没有做过类似的题目,本着学习的目的,于是我查阅了资料,在LeetCode的讨论区里得到了解答:
 
设立一个慢指针slow,一个快指针fast,慢指针每次走一步,快指针每次走两步。假设从head到环起点start的距离为x,环的长度为y(即从起点走回起点所需要走的步数)。
 
我们知道,当存在环的时候,fast和slow必然会在环中某一处相遇,假设相遇点距离start为m,于是slow和fast在m处相遇时,slow走了:x+ky+m,fast走了:x+ty+m。因为fast走的为slow的两倍,于是:
 
 
 
ty可以被y整除,所以x+m+2ky应当也能被y整除,即(x+m) mod y=0。于是,可以推断,当二者在m出相遇时,再绕环走x步,便一定可以到达环的起点。
 
可得出代码如下:
 
复制代码
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(!head) return NULL;
        ListNode* slow = head;
        ListNode* fast = head;
        do{
            if(!fast) return NULL;
            slow = slow->next;
            fast = fast->next;
            if(fast) fast = fast->next;
            else return NULL;
        }while( slow != fast );
        slow = head;
        while( slow != fast ){
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
    }
};
分享到: 更多
©2017 安全焦点 版权所有.
人才招聘联系我们