57.环形链表
题目
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
思路
快慢指针(Floyd判圈算法)
用两个指针同时出发:
- 慢指针: 每次走1步
- 快指针: 每次走2步
如果没有环: 快指针会先到达null,结束。
如果有环: 快指针会在环里一直转,慢指针进环后,快指针每轮追近1步,最终两者必然相遇。
类比: 两个人在操场跑步,跑得快的人总会追上跑得慢的人。
class Solution {
fun hasCycle(head: ListNode?): Boolean {
var slow = head
var fast = head
while (fast != null && fast.next != null) {
// 慢指针走1步
slow = slow?.next
// 快指针走2步
fast = fast.next?.next
// 相遇,有环
if (slow == fast) {
return true
}
}
// 快指针到头,无环
return false
}
class ListNode(var `val`: Int) {
var next: ListNode? = null
}
}
复杂度
- 时间复杂度: O(n),无环时快指针 n/2 步到头;有环时慢指针最多走一圈就被追上。
- 空间复杂度: O(1),只用了两个指针,没有额外空间。
- 邮箱 :charon.chui@gmail.com
- Good Luck!