学习历程-存在环形的链表中,找出起始点

原题

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

理解

一段链表,无父指针,其内可能存在环形结构,即遍历时会在某个位置的下一节点指向已经遍历过的某个位置,求发生错误位置

非原创解法
设定两个指针。一快(f)(一次走两步)一慢(s)(一次一步),一同出发,因环形链表,两点会在环形内相遇

图中,a为起始点到环形开始点的路程,b为进入环形后,相遇点到环形开始点距离,c为环形总长去掉b的距离,途中红色竖线为相遇点,黄色表示末尾点指向之前的点,也是就是指向环型开始的点

这两个指针再一段无限长的环形路上,一定会相遇,而且,因为快的指针一定是从慢的指针后面“追”上来的,快指针至少比慢的指针多走了一个(n)环形
小学二年级的知识告诉我们,f 走的总距离是 s 的两倍,T相等,2Vs=Vf,时间相等,速度是两倍
得出2a+2b=a+b+k(b+c),f 的路程为a+b+转了k圈
导出a+b=k(b+c),
也就是说两点从 链表头 和 环形开始 点一同出发,速度都为1
那他们会在s和f相遇点相遇
这时我们把公式两端都去掉一个b
a=(k-1)b+c
两个点都少走b长,头出发的点去掉总路程的后端的b,sf相遇点出发的点去点前端b长,即 速度为1的两个点一个在表头出发走了a长的时候。会碰见在sf相遇点出发的另一个点
这两个点相遇点就是环形开始点

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if (pHead == NULL)
            return NULL;
        ListNode* f, *s;
        s = f = pHead;
        
        do{
            if (s->next == NULL || s->next->next == NULL)
            {
                return NULL;
            }
            s = s->next->next;
            f = f->next;
        } while (s != f);
        f = pHead;
        while (s != f)
        {
            f = f->next;
            s = s->next;
        }
        return s;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值