目录
一.环形链表Ⅰ
1.题目描述
给你一个链表的头节点
head
,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。如果链表中存在环 ,则返回
true
。 否则,返回false
。
提示:
- 链表中节点的数目范围是
[0, 104]
-105 <= Node.val <= 105
pos
为-1
或者链表中的一个 有效索引 。
2.题解
(1)快慢指针
思路及算法:具体地,我们定义两个指针,一快一慢。慢指针每次只移动一步,而快指针每次移动两步。初始时,快慢指针都在位置
head
,这样一来,如果在移动的过程中,快指针反过来追上慢指针,就说明该链表为环形链表。如果链表中没有环,那么快指针会先到达链表尾部(null
)。
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ 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; }
复杂度分析
时间复杂度:O(N),其中 N 是链表中的节点数。
当链表中不存在环时,快指针将先于慢指针到达链表尾部,链表中每个节点至多被访问两次。
当链表中存在环时,每一轮移动后,快慢指针的距离将减小一。而初始距离为环的长度,因此至多移动 N 轮。
空间复杂度:O(1),我们只使用了两个指针的额外空间。
链接在这里哦,看完可以自己试一试:141. 环形链表 - 力扣(LeetCode)
(2)拓展
①为什么一定会相遇?
②slow走1步,fast走3步 n步呢?
(以下只讲解3步的情况,n步问题就留给大家吧~)
slow 走距离是: L fast 走的距离: L + x * C + C - N
(slow 进环时,假设 fast 已经在环里面转了 x 圈)(fast 走的距离是 slow 的3倍)3* L = L + x * C + C - N
=>2* L =( x +1)* C - N
如果同时存在 N 是奇数且 C 是偶数,那么就永远追不上
偶数=( x +1)*偶数﹣奇数
只有奇数﹣奇数才能等于偶数,但是( x +1)*偶数一定是偶数
所以反证出 N 是奇数且 C 的偶数不能同时存在,永远追不上的条件不成立
结论:一定能追上
N 是偶数第一轮就追上了
N 是奇数第一轮追不上, C-1是偶数第二轮就追上
二.环形链表Ⅱ
1.题目描述
给定一个链表的头节点
head
,返回链表开始入环的第一个节点。 如果链表无环,则返回null
。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果pos
是-1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表。
提示:
- 链表中节点的数目范围在范围
[0, 10^4]
内-10^5 <= Node.val <= 10^5
2.题解
(1) 快慢指针
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* detectCycle(struct ListNode* head) { struct ListNode *slow = head, *fast = head; while (fast != NULL&&fast->next!=NULL) { slow = slow->next; fast = fast->next->next; if (fast == slow) { struct ListNode* meet = slow; while (head != slow) { head= head->next; meet = meet->next; } return ptr; } } return NULL; }
当head走过L到入环节点,slow走了(x-1)*C+C-N到入环节点