题目
给定一个链表,判断链表中是否有环。
分析
首先可以回想追及问题:在一条操场跑道上,如果两个人跑步速度一块一慢,那么两人在同一起点开始后,最后一定会在跑到的某个节点相遇。
从此引入快慢指针的概念,定义两个指针,同样从头节点开始起步往后移动,一个指针一次移动两个节点(快指针),另外一个指针一次移动两个节点(慢指针)。如果现在链表没有环的话,那么这两个指针是一定不会再次遇见的,指针只会走到该节点没有下一节点后停下;而如果链表中有环,那么两个指针就一定辉会在链表中的某一节点相遇。用图来演示一下,假设现在有两个指针A和B,它们每次分别移动1个节点/两个节点:
这就是快慢指针的基本思路了,当然还有另外一种情况,就是两个指针永远不相遇的情况,这种情况就是链表无环的情况了,接下来用代码实现一下。
代码实现
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
// 定义两个指针
ListNode p1 = head;
ListNode p2 = head;
while (p1 != null && p2 != null) {
p1 = p1.next;
p2 = p2.next;
if (p2 != null) {
// p2指针走第二步
p2 = p2.next;
}
if ((p1!=null && p2 !=null) && p1 == p2) {
return true;
}
}
return false;
}
}
扩展思考
- 如果链表有环,如何判断出环的长度?
- 如果链表有环,如何判断出入环节点是哪一节点?