判断链表是否有环

问题:有一个单向链表,链表中可能会出现“环”,如何判断该链表是否有环呢?
在这里插入图片描述
1 从头节点开始,依次遍历单链表中的每一个节点。每遍历一个新节点,就从头检查新节点之前的所有节点,用新节点和此节点之前所有节点依次做比较。如果发现新节点和之前的某个节点相同,则说明该节点被遍历过两次,链表有环;如果之前的所有节点中不存在与新节点相同的节点,就继续遍历下一个新节点,继续重复刚才的操作。
假设链表节点为n,该解法的时间复杂度为O(n^2),并没有使用额外空间,所以空间复杂度为O(1)

2 先创建一个以节点id为Key的HashSet集合,用来存储曾经遍历过的节京。然后同样从头节点开始,依次遍历单链表中的每一个节点。每遍历一个新节点,都用新节点和HashSet集合中存储的节点进行比较,如果发现Hashset中存在与之相同的节点id,说明链表有环,如果Hashset中不存在与新节点相同的节点id,就把这个新节点id存入Hashset中,之后进入下一节点,继续重复刚才的操作
这个方法流程上和1类似,本质使用了hashSet作为额外的缓存,假设节点为n,时间复杂度为O(n),由于使用了额外的空间,所以空间复杂度是O(n)

3 在一个环行跑道上,两个运动员一个速度快,一个速度慢,跑了一段时间后,速度快的运动员总会追上速度慢的运动员,原因很简单,因为跑道是环形的
假设链表元素为n 时间复杂度为O(n),除了两个指针外,没有消耗额外空间,所以空间复杂度是O(1)

    /**
     * 判断链表是否有环
     *
     * @param head 链表头节点
     * @return true
     */
    public static boolean isCycle(Node head) {
        Node p1 = head;
        Node p2 = head;
        while (p2 != null && p2.next != null) {
            p1 = p1.next;
            p2 = p2.next.next;
            if (p1 == p2) {
                return true;
            }
        }
        return false;
    }

    /**
     * 链表结构
     */
    private static class Node {
        int data;
        Node next;

        Node(int data) {
            this.data = data;
        }
    }

    @Test
    public void test1() {
        Node node1 = new Node(5);
        Node node2 = new Node(3);
        Node node3 = new Node(7);
        Node node4 = new Node(2);
        Node node5 = new Node(6);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node2;
        System.out.println(isCycle(node1));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值