题目描述
Given head, the head of a linked list, determine if the linked list has a cycle in it.
There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail’s next pointer is connected to. Note that pos is not passed as a parameter.
Return true if there is a cycle in the linked list. Otherwise, return false.
样例描述
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed).
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
思路
- 哈希表法:用一个哈希表来存储已经出现过的结点,如果插入失败
add
方法会返回null
就说明存在过,那就是有环 - 快慢指针法:设置两个指针,快的是慢的速度的两倍,快的肯定先入环,两个指针最后一定会在某个位置相遇。注意用
while
循环的话,两个指针初始的位置别相同,否则无法进入循环体。 注意初始要判断head 和head.next
是否为空,因为没有和只有一个元素肯定无法是环 (环至少要两个元素) - 细节:0个或一个元素(容易漏掉)也无法成环
代码
- 哈希表法
public class Solution {
public boolean hasCycle(ListNode head) {
if (head == null || head.next == null) return false;
Set<ListNode> set = new HashSet<>();
while (head != null){
if (!set.add(head)) return true;
head = head.next;
}
return false;
}
}
- 快慢指针法
public class Solution {
public boolean hasCycle(ListNode head) {
//只有一个本身为空 肯定无环
if (head == null || head.next == null) return false;
//让快慢指针起始位置不同是因为后面的while循环是先判断循环条件,否则不能执行
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
}