【数据结构与算法】链表及相关问题

本文深入探讨了链表的相关操作,包括如何建立带环链表、判断链表是否带环及其环的入口与长度,链表相交问题的判断与求解,以及查找倒数第K个结点和链表中间结点的方法。所有操作均以Java实现,强调了双指针法在链表问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标题【数据结构与算法】链表及相关问题

前言

链表(Linked list)相关算法题在面试中很常见,本文将详细介绍链表相对复杂的操作,并用Java语言实现,其中包括:建立带环链表(区别于循环链表)、判断链表是否带环,求得环入口结点及环的长度;判断两个链表是否相交、求得交点;查找倒数第K个结点;反转链表。在LeetCode和剑指Offer中出现的链表问题,基本基于这几个操作。(反正我是一文搞懂啦~)其他简单的操作实现在文后链接中。
学习目的:掌握链表相关操作,熟练使用双指针法(快慢指针法)

一. 带环单链表相关问题

1. 带环单链表建立

带环链表

看过的解决带环链表问题的文章,都只讨论怎样求得环入口结点和环长度,博主这种渣渣就在想怎么不讲怎么建立带环链表,都没有办法验证……于是自己写了。

代码:

   /**
     * @description 建立一个带环单链表
     * @param head
     */
    public void createLoopList(Node<E> head) {
   
        int i;
        Node<E> current = head;
        Node<E> target = null;
        for (i = 0; i < 10; i++) {
   
            Node<E> temp = new Node(i);
            temp.next = null;
            current.next = temp;
            this.size++;
            if (i == 6)
                target = temp;//指定这个结点为环的第一个结点
            current = temp;
        }
        current.next = target;  //链表末端指向中间的一个结点,这样就创建了一个带环单链表
    }
2. 判断链表是否带环

算法思想:图中是一个带环单链表,这里要区分,循环链表并非这里所讨论的带环单链表。这里判断链表是否带环采用的便是的双指针法,之后也会常用到此方法,应用双指针的算法时间复杂度为O(n),空间复杂度为O(1)。双指针法,即设置快慢指针,在判断是否带环时,我们让快指针每次走两个步长(即fast=fast->next->next),慢指针每次走一个步长(即slow=slow->next),这样一来,如果链表带环,则快指针早晚会经过不懈努力再次追赶上慢指针,并且两指针一定在环上相遇。

 p.s.:也可以通过设置标志位的方法,但是空间复杂度较高。
代码

   /**
     * @return
     * @description 判断单链表是否有环(双指针法)--时间复杂度O(n);空间复杂度O(1)[设置标志位空间复杂度大]
     */
    public boolean hasLoop() {
   
        Node<E> pre = head.next;
        Node<E> post = head.next;

        if (pre == null)
            return false;
        while (pre != null && pre.next != null && pre.next.next != null) {
   
            post = post.next;   //慢指针走一步
            pre = pre.next.next;   //快指针走两步
            if (pre == post)
                return true;
        }
        return false;

    }
3. 求环入口结点

在这里插入图片描述
算法思想:找到环的入口结点,仍然使用双指针法,我们设入口结点到头结点距离为e,快慢指针相遇点到头结点距离为m,设环的长度为L,快指针与慢指针相遇时,慢指针走s步,则快指针走2s步,且快指针追上慢指针是在走了n次环的长度之后,则有: s = e + m s=e+m s

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值