给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。

进阶:
你能用 O(1)(即,常量)内存解决此问题吗?

示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle

解法一 快慢指针

分析

慢指针走一步,快指针走两步,如果快指针最终能追上慢指针,说明有环。
注意循环条件判断

代码

  1. public class Solution {
  2. public boolean hasCycle(ListNode head) {
  3. if(head==null||head.next==null) return false;
  4. ListNode slow = head, fast = head.next;
  5. while(slow!=fast){
  6. if(fast==null||fast.next==null){
  7. return false;
  8. }
  9. slow = slow.next;
  10. fast = fast.next.next;
  11. }
  12. return true;
  13. }
  14. }

时间复杂度O(n)
空间复杂度O(1)

解法二 哈希表

分析

将节点加入HashSet中,如果加入失败,说明有环,否则没环。

代码

  1. public class Solution {
  2. public boolean hasCycle(ListNode head) {
  3. Set<ListNode> set = new HashSet<ListNode>();
  4. while (head != null) {
  5. if (!set.add(head)) {
  6. return true;
  7. }
  8. head = head.next;
  9. }
  10. return false;
  11. }
  12. }

时间复杂度O(n)
空间复杂度O(n)