美文网首页
链表的环相关问题

链表的环相关问题

作者: _空格键_ | 来源:发表于2020-05-07 16:57 被阅读0次

题目

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
说明: 不允许修改给定的链表。

链表节点环图示

解题

方法 1:哈希表

使用一个 Set /List保存已经访问过的节点,我们可以遍历整个列表,检查每一个节点是否已存在Set中,如果存在即可返回第一个出现重复的节点,否则不存在环返回null。

1.1 算法

public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> visited = new HashSet<ListNode>();

        ListNode node = head;
        while (node != null) {
            if (visited.contains(node)) {
                return node;
            }
            visited.add(node);
            node = node.next;
        }

        return null;
    }
}

1.2 复杂度分析

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

方法 2:Floyd 算法

也称双指针/快慢指针法。就是用两个指针,从头开始遍历,一个指针步进+1,一个指针步进+2,如果链表存在环,这两个指针总会相遇。想象下环形操场,两个人同起点同方向跑步,一个快一个慢,他们总会在某一点相遇,同理。

2.1 算法

本算法分两步:第一步检查是否存在环,第二部如果存在环,找出环的入口。

通过数学模型计算,第一次相遇后,快慢指针走过的距离 2S慢=S快,即

2(F + a) = F + N(a + b) + a
2F + 2a = F + 2a + b + (N - 1)(a + b)
          F = b + (N - 1)(a + b)

  • F是到达入口点长度
  • N为快指针跑过第几个整圈后会与慢指针相遇

下图便于理解


环算法模型
public class Solution {
    private ListNode getIntersect(ListNode head) {
        ListNode tortoise = head;
        ListNode hare = head;

        // 如果存在环,一定会相遇;如果不存在环,hare最先到达null
        while (hare != null && hare.next != null) {
            tortoise = tortoise.next;
            hare = hare.next.next;
            if (tortoise == hare) {
                return tortoise;
            }
        }

        return null;
    }

    public ListNode detectCycle(ListNode head) {
        if (head == null) {
            return null;
        }

        //寻找相遇点,如果存在环,返回相遇点;如果不存在,返回null
        ListNode intersect = getIntersect(head);
        if (intersect == null) {
            return null;
        }

        // 寻找入环点,需要两个指针+1速度,一个从头开始,一个从相遇点开始,两个指针相遇时即为环入口
        ListNode ptr1 = head;
        ListNode ptr2 = intersect;
        while (ptr1 != ptr2) {
            ptr1 = ptr1.next;
            ptr2 = ptr2.next;
        }

        return ptr1;
    }
}

2.2 复杂度分析

  • 时间复杂度O(n)
    如果存在环,遍历实现以慢指针次数为准;如果不存在环,遍历时间以快指针次数为准。
  • 空间复杂度O(1)
    只开销了几个指针变量

[注]
详细参考: LeetCode 142.环形链表 II

相关文章

  • 链表的环相关问题

    题目 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。说明: 不允许修改给定的链表。...

  • 1.数据结构-链表问题

    链表相关问题 删除节点 链表去重 有环链表 反转链表 链表排序 链表相交 其他问题 面试题 02.03. 删除中间...

  • 有环单链表的相关问题

    问题:判断单链表是否有环;若有环,找出环的入口节点;若有环,求出环上节点的个数;若有环,求出整个链表的节点的个数;...

  • 算法学习--双指针

    双指针分类 快慢指针 左右指针 快慢指针:主要解决链表相关问题,比如:典型的判断链表中是否包含环、链表倒是第K个节...

  • 链表算法面试?看我就够了!——链表中存在环问题

    链表中存在环问题 3.1 判断链表是否有环 单链表中的环是指链表末尾的节点的 next 指针不为 NULL ,而是...

  • 单链表环相关

    一、单链表[https://www.jianshu.com/p/3aa144ac4c3b]问题 1️⃣给一个单链表...

  • 数据结构-链表

    相关掌握点 单向链表 双向链表 反转单向链表 判断链表是否含有环 链表构建 链表是一种线性结构,是通过指针引用节点...

  • 2020-08-19

    单链表找环(floyd算法) 首先是示意图,链表中有环就是这种情况 问题是,在这样一个单链表中,若有环,寻找出环的...

  • 链表-链表有环问题

    1. 判断一个单向链表是否有环 有环的链链表大概张这样 有环的链表和普通的链表的区别就是尾指针指向了链表中的某一个...

  • Swift - LeetCode - 环形链表 (2)

    题目 环形链表 2 问题: 给定一个链表,返回链表开始入环的第一个节点、如果链表无环、泽返回NULL 说明: 不允...

网友评论

      本文标题:链表的环相关问题

      本文链接:https://www.haomeiwen.com/subject/nqioghtx.html