原题: 链表中环的检测
- 第一种题解,思路从每个对象其实是引用地址如果next下标指针的引用内存地址已经在set集合存在则说明链表中有环
public boolean hasCycle(ListNode head){
//首先定义个集合set
Set<ListNode> set = new HahSet<>();
//判断当前head节点是否为空,如果为空则说明没有或者尾节点循环的退出条件
while(head != null){
if(set.contain(head)){
return true;
}else{
set.add(head);
}
head = head.next;
}
return false;
}
时间复杂度O(n),空间复杂度O(n)
- 方法二:双指针
通过使用具有 不同速度 的快、慢两个指针遍历链表,空间复杂度可以被降低至 O(1)O(1)。慢指针每次移动一步,而快指针每次移动两步。
如果列表中不存在环,最终快指针将会最先到达尾部,此时我们可以返回 false。
public boolean hashCycle(ListNode head){
//边界条件
if(head== null || head.next == null){
return false;
}
//定义两个指针
ListNode slow = head;
ListNode fast = head.next;
//开始两个指针赛跑
while(slow != fast){
//退出循环查询条件
if(fast== null || fast.next == null){
return false;
}
//如果不为空则依次迭代fast2步,slow1步
slow = slow.next;
fast = fast.next.next;
}
return true;
}