题目介绍及扩展
题目介绍
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
leetcode链接
示例一:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例二:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例三:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
题目扩展
slow
和fast
分别是慢快指针
问题一:
slow
和fast
一定能相遇吗?
问题二:
slow
走一步,fast
走三步可以吗,走四步呢?
思路介绍
首先定义两个指针slow
(一次走一步)和fast
(一次走两步)
对于无环的情况,fast
会走到NULL
而停止
对于有环的情况:
当slow
刚进入环中时(即上图所示位置时),假设两指针此时的距离为N,slow走一步,fast走两步,N会逐渐减小(N由N逐渐变为N - 1, N - 2, ···, 3, 2, 1, 0),当N变为0时,两指针就会相遇,所以快慢指针的方法就可以判断链表是否有环
问题一:
上述思路说明两指针一定会相遇
问题二:
假设slow
一次走一步,fast
一次走三步,当slow
刚刚进环时,两指针的距离为N,
此时若N为偶数时,N会由N逐渐减小变为N - 2, N - 4, ······, 4, 2, 0,两指针刚好相遇
此时若N为奇数数时,N会由N逐渐减小变为N - 2, N - 4, ······, 5, 3, 1, -1,此时,fast
会跳过slow
,假设整个环的长度为C,若C-1为偶数,则两指针会相遇,若C-1为奇数,则两指针永远不会相遇了。
当fast
走四步或更多时,思路同上。
代码展示
bool hasCycle(struct ListNode *head)
{
struct ListNode* slow = head;
struct ListNode* fast = head;
while (fast && fast->next)
{
//移动指针
slow = slow->next;
fast = fast->next->next;
//在循环中判断两指针地址是否相同
if (slow == fast)
{
return true;
}
}
return false;
}