Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
题目:输入一个链表的头节点,检查这个链表是否有环。(能否设计一种不占用额外空间的算法?)
实现思路1(占用额外空间):这种思路比较直观,即用一个Set保存每次遍历到的节点(Set里边存的是节点的引用),如果当前节点已经在Set中就说明链表有环,如果当前节点是null就说明链表无环。
public class Solution {
public boolean hasCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
while (head != null) {
if (set.contains(head))
return true;
else
set.add(head);
head = head.next;
}
return false;
}
}
实现思路2(不占用额外空间):使用快慢两个指针,即如果链表有环,移动速度快的指针一定会追上速度慢的指针。具体来说,令慢指针每次移动一个节点、快指针每次移动两个节点,如果快慢指针相遇(指向相同的节点)就说明链表有环,如果快指针是null或快指针的下一个节点是null就说明链表无环。
public class Solution {
public boolean hasCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) return true;
}
return false;
}
}
参考资料:
https://leetcode.com/problems/linked-list-cycle/solution/
https://leetcode.com/problems/linked-list-cycle/discuss/44489/O(1)-Space-Solution