142. 环形链表 II - 力扣(LeetCode) (点击前方链接即可查看题目)
给定一个链表的头节点
head
,返回链表开始入环的第一个节点。 如果链表无环,则返回null
。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果pos
是-1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点。示例 2:
输入:head = [1,2], pos = 0 输出:返回索引为 0 的链表节点 解释:链表中有一个环,其尾部连接到第一个节点。示例 3:
输入:head = [1], pos = -1 输出:返回 null 解释:链表中没有环。提示:
一、解法一
判断有环请参考:环形链表 - 力扣(LeetCode) C语言-CSDN博客
看完判断有环之后,就只剩下寻找环的第一个结点: (C为圆环长度)
fast和slow在环相遇时,slow走了L+X, fast走了L+nC+X(n >= 1, 因为环可能大可能小, 若为大环, fast追击一圈即可追上slow, 若为小环,slow还没有进环时,fast已经转了好几圈了)
因为slow走一步,fast走两步,所以距离关系如下:
化简得:
即:
其中: (C-X) 是相遇时未走完一圈的剩余路程, 所以将slow重新从head走到环的第一个结点时,
meet和slow一样一次走一步,当slow到达第一个结点时,meet也刚刚好到达第一个结点.
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode *detectCycle(struct ListNode *head)
{struct ListNode* fast = head;struct ListNode* slow = head;struct ListNode* meet = NULL;while(fast && fast->next){fast = fast->next->next;slow = slow->next;if(fast == slow){meet = fast;slow = head;while(slow != meet){slow = slow->next;meet = meet->next;}return meet;}}return NULL;
}
二、解法二:转化为相交链表
还是找到meet点时,将meet->next = NULL; 此变成了相交链表求解,第一个交点
解法请参考相交链表 - 力扣(LeetCode)C语言-CSDN博客