题目:判定一个单链表是否有环?
这是一个比较常见且经典的算法题目。
在思考怎么实现前,我们要先思考一下怎么样的单链表才算有环?
例如:
但是,不止这种
以下的几种单链表都是有环
- 环形链表:
- 尾部有环:
实现逻辑:
判断该单链表是否有环,其实就是链表无终点的现象,但是我们无法单纯地通关无重点来返回判断结果。
所以我们需要中这个循环的过程,使用快、慢两个指针在循环中追逐,直到相遇,此时就可以判定该单链表有环。
指针fast、slow都起始于同一位置
每次slow移动一个节点,fast移动两个节点
因为fast节点移动速度快于slow节点,如果存在环,则会相遇的那一刻(即slow=fast),这样则可以判断当前链表存在环,返回true;
如果slow节点为空,或者fast为空,或者fast的下一节点为空,即链表有终点,则返回false;
源码
public static boolean hasCycle(ListNode node){
//判断当前链表节点是否为空以及是否拥有下一节点
if (node==null||node.next==null){
return false;
}
//使fast和slow起始于开始节点
ListNode slow = node;
ListNode fast = node;
//当链表不存在终点时
while(slow!=null&&fast!=null&&fast.next!=null){
//slow节点移动一个节点位置
slow = slow.next;
//fast节点移动两个节点位置
fast = fast.next.next;
//当两个节点相遇时
if(slow == fast){
return true;
}
}
return false;
}
判断fast.next!=null,是因为fast每次移动两个节点,必须保证fast的下一节点不为空
同时为了fast可以查询next,必须保证fast不为空;