欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[剑指offer-23]链表中环的入口节点

程序员文章站 2022-06-17 17:22:07
...

[23]链表中环的入口节点

1.题目

如果一个链表中包含环,如何找出环的入口节点?

2.思路

快慢指针扫描

  1. 用两个指针firstsecond分别从起点开始走。
  2. first每次走一步,second每次走两步
  3. 如果过程中second走到null,说明没有环
  4. 否则当 firstsecond 相遇后,让 first 返回起点,second 待在原地不动,然后两个指针每次分别走一步,当相遇时,相遇点就是环的入口

[剑指offer-23]链表中环的入口节点

证明

aa 是起点,bb 是环的入口,cc 是两个指针的第一次相遇节点

  • abab 之间的距离为 xx

  • bcbc 之间的距离为 yy

  • cbcb 之间顺时针距离为 zz

在第一次相遇时

first走的距离 x+yx+y

second走的距离 x+n(z+y)+yx+n(z+y)+ynn表示圈数

second走的距离是first的两倍
x+n(z+y)+y=2(x+y)x=(n1)×(y+z)+z x+n(z+y)+y = 2(x+y)\\ \Rightarrow x=(n−1)×(y+z)+z
那么:

secondcc 点走 xx 步,恰好到 bb

firstaa 点走 xx 步,也能到 bb

3.代码

class Solution {
public:
    ListNode *entryNodeOfLoop(ListNode *head) {
        if(!head || !head->next)  return 0;
        
        ListNode *first=head;
        ListNode *second=head;
        
        while(first && second)
        {
            first = first->next;
            second = second->next->next;  
          
            if(first==second) //相遇后,first返回head,first和second都只走一步
            {
                first=head;
                while(first != second)
                {
                    first = first->next;
                    second = second->next;
                }
                
                return first;
            }
        }
        return 0;
    }
};