面试题 02.08. 环路检测

面试题 02.08. 环路检测
给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点。若环不存在,请返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:

输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:

输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。

进阶:

你是否可以不用额外空间解决此题?

题解

作者很牛逼,整理一下思路

  1. 利用快慢指针判断有没有环

  2. 如果有,则快慢指针会在某点相遇,因为快指针多跑了,但相遇的点不一定是环的入口。

  3. 不妨设链表的头节点到环的入口节点的距离为s1,入口节点到二者相遇点的距离为s2 我们得到这样一个各自所跑的距离

    image-20220414115016567

  4. 快指针移动的距离是y1=( s1+s2+xn)快指针先从头节点跑到相遇节点,然后在环里不断的跑,n为次数,x为跑的圈数,直到遇到慢指针

  5. 慢指针移动的距离是y2=(s1+s2)慢指针从头节点跑到二者相遇的阶段

  6. 二者存在一个潜在的等量关系,y1=2y2,即是(s1+s2+xn)=2(s1+s2)

  7. 整理一下s1+s2=xn

  8. 进一步整理:s1=(n-s2)+(x-1)n

  9. 由s1+s2=xn知道快指针移动s1步,到达入口,慢指针也移动s1步,换算成上面这个等式,(x-1)n等于绕圈,没动,实际移动了(n-s2),也到达了入口。

  10. 然后从头结点和相遇节点开始同时步长为1遍历 当两个相同时 必定移动了s1步此时返回指针所指位置,就是入口。

代码

/**
 * 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 *fast = head, *slow = head;
		while (slow&&fast&&fast->next)
		{
			slow = slow->next;
			fast = fast->next->next;
			if (fast == slow)
			{
				while (head != fast) {
					head = head->next;
					fast = fast->next;
				}
				return head;
			}
		}
		return NULL;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值