题目
题解一 :采用map集合
将链表遍历得到每一个节点的值放入map作为key,直到有重复的,那么就是循环链表
public static boolean hasCycle(ListNode head) {
Map<ListNode, Integer> map = new HashMap<>();
//若链表为空直接false
if (head == null) {
return false;
}
//遍历链表
while (head.next!=null) {
//判断map有没有该元素 key重复 重复代表是出现了循环链表 直接false
if (map.containsKey(head)) {
return true;
} else {
//若不包含重复的key 则加入map
map.put(head, head.val);
}
//遍历
head = head.next;
}
//正常链表会循环到null
return false;
}
题解二:set集合——>去重
set 集合的add方法在添加元素时会去重,
若添加的不是重复的会返回true,
若添加的是重复的会返回false,
/**
*set实现
* @param head
* @return
*/
public static boolean hasCycle(ListNode head) {
//若链表为空直接返回false
if (head == null) {
return false;
}
Set<ListNode> set = new HashSet<>();
//遍历链表
while (head.next!=null) {
//set 集合的add方法在添加元素时会去重,
// 若添加的不是重复的会返回true,
// 若添加的是重复的会返回false,
boolean addBoolean = set.add(head);
if (!addBoolean) {
return true;
}
//遍历
head = head.next;
}
//正常链表会循环到null
return false;
}
题解三:快慢指针
只要链表是循环链表,设置两个指针,一个慢指针(一次只走一步),一个快指针(一次走多步),那么肯定会在某一个节点两个指针会相遇。
参考官方解答:快慢指针
/**
* 快慢指针实现
* 只要链表是循环链表,设置两个指针
* 一个慢指针(一次只走一步),一个快指针(一次走多步)
* 那么肯定会在某一个节点两个指针会相遇。
* @param head
* @return
*/
public static boolean hasCycle(ListNode head) {
//若链表为空直接返回false
if (head == null || head.next == null) {
return false;
}
//定义快慢指针
ListNode slow = head;
ListNode fast = head.next;
//循环结束条件为快慢指针相遇
while (slow != fast){
//任何一个指针只要跑到了为null的节点,说明链表不是循环链表
if (fast == null || fast.next == null) {
return false;
}
//指针往前跑
slow = slow.next;
fast = fast.next.next;
}
//若两个指针相遇了,可以说明链表是循环链表
return true;
}