LeetCode——linked-list-cycle-ii 判断链表是否有环,如果有,返回环的入口

LeetCode——linked-list-cycle-ii 判断链表是否有环,如果有,返回环的入口

题目描述:
Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull.

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

题目分析:
如果可以用额外空间,可以建立map,存放访问节点的地址,如果访问到一个已经访问过的节点,说明有环,返回第一个重复访问节点的地址。

题目要求不要用额外空间,看可以用双指针法。慢指针每次走一步,快指针每次走两步。
具体原理请看灵魂画手精心绘图~
在这里插入图片描述
如果没有环,那么快指针将率先到达终点。
在这里插入图片描述
如果有环,那么二者终将相遇。
这事,慢指针的走了L+S,快指针比慢指针多走了环周长的n倍(多走了n圈),即 L+S+nR。
而慢指针应为慢指针的2倍,即
(L+S)2=L+S+nR
nR=L+S
L=n
R-S
如果一个指针从Begin出发,另一个从Meet处出发,那么终将在入口相遇。
AC代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* step_one=head;//都从头结点出发
        ListNode* step_two=head;//都从头结点出发
        int flag=0;
        while(step_one!=step_two||flag==0)//没相遇就一直走(都在起点时不算相遇)
        {
            flag=1;
            step_one=step_one->next;//慢指针走一步
            if(step_two!=NULL&&step_two->next!=NULL)
                step_two=step_two->next->next;//快指针走两步
            else 
                return NULL;//如果走到头说明没有环
        }
        ListNode* StartFromBegin=head;//从头结点出发
        ListNode* StartFromCross=step_one;//从相遇节点出发
        while(StartFromBegin!=StartFromCross)//每次走一步,直达相遇
        {
            StartFromBegin=StartFromBegin->next;//
            StartFromCross=StartFromCross->next;//
        }
        return StartFromBegin;//相遇节点即为入口
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值