【LeetCode-Java实现】141. Linked List Cycle

141. Linked List Cycle

题目描述

Given a linked list, determine if it has a cycle in it.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
在这里插入图片描述
在这里插入图片描述
Follow up:
Can you solve it using O(1) (i.e. constant) memory?
判断一个线性链表里是否有环,要求空间复杂度为O(1)
输入:该线性链表、链表尾部元素 连接的元素的下标(若没有环,则为-1)
输出:是否存在环

解题思路

两种思路:

  1. HashSet——这个思路比较好想,逻辑比较简单
    (1)先创建一个HashSet来存放head里的元素(HashSet不允许重复,元素无序)
    (2)逐个遍历Linked List里的元素:若HashSet里不含有当前元素,就加入到HashSet里; 若HashSet里含有该元素了,说明 当前遍历到的元素是尾部元素连接的元素,也就说明存在环。
    (3)若一直遍历到最后都没有元素在HashSet里已经存在过,说明无环
    在这里插入图片描述

  2. 双指针—— 这个就非常巧妙了,也比较难想
    (1)定义两个ListNode类型变量:slow、fast
    (2)两个变量同时在Linked List里前进:slow跑得慢,一次只前进一步;fast跑得快,一次前进两步。
    (3)如果有环,slow和fast必定会相遇。
    在这里插入图片描述

实现代码

根据上述思路可得Java代码:.
思路1:hashSet

public boolean hasCycle(ListNode head) {
        Set<ListNode> s = new HashSet<>();
        while (head != null) {
            if (s.contains(head)) {   //若HashSet里已经存在当前遍历到的元素,说明有环
                return true;
            } else {
                s.add(head);    //若没有就加进去
            }
            head = head.next;
        }
        return false;    //遍历结束了都没遇到已存在的结点,说明没环
    }

思路2:双指针

public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null) {   //先进行异常情形判断
            return false;
        }
        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;   //slow 和fast相遇,说明有环
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值