114.环形链表
题目
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。1
2
3
4
5示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
方法
方法1:哈希表 & 字典
判断链表是否有环,只需要按段在当前结点之前的结点是否访问过。采用哈希表
逐个结点遍历,并且用哈希表记录每个节点的 reference (or memory address) 。如果当前节点是None,即遍历指针到达链表的尾部,说明该链表一定不是环形的。如果当前结点的reference在哈希表里,则一定是环形的。
- 时间复杂度:O(N),最多访问链表里的所有元素N。增加结点到字典里,仅花费时间O(1)
- 空间复杂度:O(N),空间进决定于加入到哈希表的元素数量,最多包含N个元素
1 | # Definition for singly-linked list. |
方法2:快慢指针
两个指针速度不一样:慢指针和快指针。慢指针每次移动一个结点,快指针每次移动两个结点。
如果链表中没有环形,快指针会最终到达终点None。
如果链表中有唤醒,假设快慢指针是在环形跑步的两个runner,快指针最终会遇上慢指针。假设快指针尽在慢指针后一步,那么下一次迭代,快指针走两步,慢指针走一步,这是快慢指针就遇上了。
时间复杂度:O(n),n表示链表中的元素数量。
- 如果无环,O(n)
- 如果有环,将链表分为有环和无环部分。
- 在到达环之前,慢指针走了“non-cycic length”。此时,快指针已经到达环。$ 迭代次数=non-cycic length=N$
- 当快慢指针都在环内。快指针走两步,慢指针走一步,速度差是1,当快指针追上慢指针需要迭代次数是。距离最多是环的长度”cycle length K”,速度差是1.所以$迭代次数=almost ‘cycle length K’$
因此,最差的时间复杂度是O(N+K),那就是O(n)
- 空间复杂度:O(1),只采用快慢指针,所以是O(1)
1 | # Definition for singly-linked list. |