一、题目要求
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
二、初步解法
2.1 初步思想
采取空间复杂度较大的暴力解法
既然每个结点都有自己独立和表示,那就直接使用HashMap将遍历过的结点作为key传入Map中,当遍历过程中发现key已经存在Map中,说明有环(遍历回来了)。如果链表没有环,那么最终会遍历到null结点。
2.2 代码实现
public class Solution {
public boolean hasCycle(ListNode head) {
Map<ListNode,Integer> map=new HashMap<>();
while(head!=null) {
if(map.get(head) == null) {
map.put(head,0);
head = head.next;
}
else {
return true;
}
}
return false;
}
}
2.3 运行结果
空间复杂度O(N),时间复杂度O(N)。
三、优化解法
3.1 算法思想
采取双指针法,慢指针slowPtr一次走一步,快指针fastPtr一次走两步,早晚相遇。
如果没有环,快指针会先走到null。
节约了额外的空间资源。
3.2 代码实现
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode slowPtr = head;
ListNode fastPtr = head;
while(fastPtr!=null) {
fastPtr = fastPtr.next;
slowPtr = slowPtr.next;
if(fastPtr != null) {
fastPtr = fastPtr.next;
} else {
return false;
}
if(fastPtr == slowPtr) {
return true;
}
}
return false;
}
}