《剑指offer》-链表找环入口

简介: 题目描述一个链表中包含环,请找出该链表的环的入口结点。初步想法是每个节点做几个标记,表示是否被访问过,那么遍历链表的时候就知道哪个被访问到了。但是不会实现。另一个直觉是判断链表有环的算法中出现过的策略,分别按1x和2x速度遍历,总会相遇。

题目描述
一个链表中包含环,请找出该链表的环的入口结点。

初步想法是每个节点做几个标记,表示是否被访问过,那么遍历链表的时候就知道哪个被访问到了。但是不会实现。

另一个直觉是判断链表有环的算法中出现过的策略,分别按1x和2x速度遍历,总会相遇。假设环长为n。
容易知道,当1x的指针p1和2x的指针p2相遇时,p1走了x步,p2走了2x步,而p2比p1多走的,有两部分:(1)环内部,p1还没有走过的;(2)换内部,p1和p2重合的
这两部分加起来就是整个环。那么其实p2比p1多走的就是这么一个环的距离,也就是说:

2x-x = n  ==> n=x

即:p1当前走了一个环长度的距离。

下图表示了p1和p2相遇在B点的情况,其中A点开始顺时针方向回到A的轨迹就是环形,长度为n。

img_29d85ee93f804bdced5dc8e98a49b430.png

不妨假设链表总长为L,那么:
CA+A环=CA+n=L ==>L-n=CA
CB=x=n=A环
==> BA弧=L-CB=L-n=CA

也即:BA弧=CA,那么指针p1从B继续走,而指针p2从链表起点C从新开始(但是步长这次取1),则当p2到达A点时,p1也到达A点。
对应到算法中,当1x和2x套圈时,p1和p2按照这个策略继续做while循环,直到再次相遇,就找到了环的入口。

/*
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;
        }
        if(pHead->next==NULL){
            return NULL;
        }
        ListNode* p1=pHead;
        ListNode* p2=pHead;
        while(p2!=NULL && p2->next!=NULL){
            p1=p1->next;
            p2=p2->next->next;
            if(p1==p2){
                p1 = pHead;
                while(p1!=p2){
                    p1=p1->next;
                    p2=p2->next;
                }
                if(p1==p2){
                    return p1;
                }
            }
        }
        return NULL;
    }
};
目录
相关文章
|
23天前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
40 0
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
50 5
|
3月前
|
Python
【Leetcode刷题Python】剑指 Offer 18. 删除链表的节点
Leetcode题目"剑指 Offer 18. 删除链表的节点"的Python解决方案,通过使用双指针法找到并删除链表中值为特定数值的节点,然后返回更新后的链表头节点。
40 4
|
6月前
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
【一刷《剑指Offer》】面试题 17:合并两个排序的链表
|
6月前
【一刷《剑指Offer》】面试题 16:反转链表
【一刷《剑指Offer》】面试题 16:反转链表
|
6月前
【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点
【一刷《剑指Offer》】面试题 15:链表中倒数第 k 个结点
|
6月前
|
机器学习/深度学习
【一刷《剑指Offer》】面试题 13:在 O(1) 时间删除链表结点
【一刷《剑指Offer》】面试题 13:在 O(1) 时间删除链表结点
|
6月前
【一刷《剑指Offer》】面试题 5:从尾到头打印链表
【一刷《剑指Offer》】面试题 5:从尾到头打印链表
|
6月前
剑指 Offer 18. 删除链表的节点
剑指 Offer 18. 删除链表的节点
42 0
|
6月前
剑指Offer06.从尾到头打印链表
剑指Offer06.从尾到头打印链表
39 0