环形链表Ⅰ(判断环形链表)
题目描述:
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
- 具体示例等请通过链接访问原题
题目链接
解题思路
我们使用快慢指针的方法做
- 如果该链表带环,那么快指针在走的过程中一定会追上慢指针,反之两指针一定遇不上
- 当两指针位置相同时(自slow向后走一步后),即证明该链表带环
代码
bool hasCycle(struct ListNode *head) {
struct ListNode *slow = head,*fast = head;
while(fast && fast->next)//如果fast或fast->next为空,肯定不是环形链表
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)//判断条件
{
return true;
}
}
return false;
}
环形链表Ⅱ(寻找入环的第一个节点)
题目描述:
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改链表。
- 具体示例请通过链接访问原题
解题思路
我们可以思考一下为什么快慢指针中fast一次走两步而不是三步甚至更多。
当fast每次走两步时有:
当fast每次走三步时有:(非必知)
走三步和下一个结论是便于更清晰的理清题目的,可以大致了解
因此我们有一个结论:
这个结论了解即可,不是解题必须
解题关键结论
代码
struct ListNode* detectCycle(struct ListNode* head) {
struct ListNode* slow = head, * fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
struct ListNode* meet = slow;
while (meet != head)
{
meet = meet->next;
head = head->next;
}
return meet;
}
}
return false;
}