Leetcode#142(链表)-Linked List Cycle II

5 篇文章 0 订阅
4 篇文章 0 订阅

题目:

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.

思路:

1.首先判断链表中是否有环,参考leetcode#141题。

2.沿用leetcode#141题中判断链表中是否含环的方法。在链表头设置两个标记分别为slow和fast,slow每次往后移动1步,fast每次往后移动2步。若链表中有环,则slow和fast肯定会相遇于环中某个节点。

3.见下图,设链表头结点为A,环的起始结点为B,slow和fast相遇与C点(相遇时slow在环内走过的距离小于等于一个环的周长),设AB间(链表头结点和环起始结点)的距离为s1,BC间(环起始结点和相遇结点)的距离为s2,环的周长为c,相遇时slow走过的距离为k,则fast走过的距离为2k,此时fast绕环次数为n。从问题中,可以提炼出以下几个公式:

①k=s1+s2;

②2k=s1+cn+s2;

联立①②,可得s1=cn-s2,即s1=c(n-1)+c-s2,c-s2即C到B要走的距离(顺时针)。

由上式可知,当fast和slow第一次相遇时,在链表头新建一个entry标记(设置其每一次往后移动距离为1,与slow速度一致),继续让三个标记往后移动,entry和slow一定会相遇于一点,该点即为环的起始结点。


通过代码:

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast!=NULL&&fast->next!=NULL&&fast->next->next!=NULL){
            slow = slow->next;
            fast = fast->next->next;
            if(slow==fast){//slow和fast相遇时在头结点新建entry标记
                ListNode* entry = head;
                while(entry!=slow){ //entry和slow相遇时跳出循环
                    entry = entry->next;
                    slow = slow->next;
                }
                return entry;
            }
        }
        return NULL;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值