【数据结构OJ题】链表带环问题

这篇具有很好参考价值的文章主要介绍了【数据结构OJ题】链表带环问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.判断链表是否带环

证明

2.寻找环的入口点


1.判断链表是否带环

原题链接:力扣

【数据结构OJ题】链表带环问题,数据结构,数据结构,链表,算法

思路一:先遍历一遍链表,计算出链表的长度,然后将长度除二,在遍历半个链表即可。但是这种方法效率比较低。

思路二:使用快慢指针,慢指针每次走1步,快指针每次走2步,当快指针走到末尾是,慢指针的位置就是链表中间位置。

下面我们使用思路二来完成题目:

bool hasCycle(struct ListNode* head) 
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
        {
            return true;
        }
    }
    return false;
}

证明

1.为什么快指针每次走两步,慢指针走一步可以追上?

2.快指针一次走3步,走4步,...n步行吗?

证明:假设slow进环以后,fast和slow的距离是N

这时fast真正开始追击slow,fast一次走2步,slow一次走1步,他们之间的距离每次缩小1

【数据结构OJ题】链表带环问题,数据结构,数据结构,链表,算法

假设slow进环以后,fast和slow的距离是N

这时fast真正开始追击slow,fast一次走3步,slow一次走1步,他们之间的距离每次缩小2

这时候要分情况讨论:

【数据结构OJ题】链表带环问题,数据结构,数据结构,链表,算法

 

2.寻找环的入口点

原题链接:力扣

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

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

不允许修改链表。

【数据结构OJ题】链表带环问题,数据结构,数据结构,链表,算法

方法一:用一个指针从链表的头节点出发,另一个指针从链表相遇的节点出发,当这两个指针相遇时,说明它们到达了入口

下面是原理:

【数据结构OJ题】链表带环问题,数据结构,数据结构,链表,算法

 代码实现:

struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
        {
           struct ListNode *meet=slow;
           while(meet!=head)
           {
               meet=meet->next;
               head=head->next;
           }
           return meet;
        }
    }
    //如果链表没有环就返回空
    return NULL;
}

方法二:可以将这个题转化成两个链表相交的问题。

将meet的下一个节点设置成newHead,求出head到meet的长度n, newHead到meet的长度m, 再利用快慢指针,使长的链表先走fabs(m-n)次,再同时走,当两个指针想等时,就到达了环的入口。

【数据结构OJ题】链表带环问题,数据结构,数据结构,链表,算法

 代码实现:

struct ListNode* detectCycle(struct ListNode* head)
{
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (slow == fast)
        {
            struct ListNode* meet = slow;
            struct ListNode* moveA = slow;
            struct ListNode* moveB = head;

            //计算两链表的长度
            int lenA = 0;
            int lenB = 0;
            while (moveA != meet)
            {
                moveA = moveA->next;
                lenA++;
            }
            while (moveB != slow )
            {
                moveB = moveB->next;
                lenB++;
            }

            //计算长度差
            int gab = fabs(lenA - lenB);
            
            struct ListNode* longList = head;
            struct ListNode* shortList = slow;
            if (lenA < lenB)
            {
                longList = slow;
                shortList = head;
            }
            //让长的链表先走
            while (gab--)
            {
                longList = longList->next;
            }

            while (longList != shortList)
            {
                longList = longList->next;
                shortList = shortList->next;
            }
            return longList;
        }
    }

    //不相交返回空
    return NULL;
}

很明显的看出来,使用方法二的代码比方法一要复杂的多文章来源地址https://www.toymoban.com/news/detail-518653.html

到了这里,关于【数据结构OJ题】链表带环问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构——链表OJ题

    目录   1.给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。 2.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 3.变形题:找到链表中倒数第k个

    2024年02月21日
    浏览(41)
  • 【数据结构初阶】链表OJ

    OJ 方案一: 题目解析: 方案二: 题目解析:把原链表遍历一遍,插入新链表 OJ 题目解析: OJ 题目解析: OJ 题目解析: OJ 题目解析: OJ 题目解析: OJ 题目解析: OJ 题目解析: 定义快慢指针,使快指针先走与慢指针同步。然后同时走看是否相交 OJ 题目解析: OJ 题目解析:

    2024年02月05日
    浏览(51)
  • 【数据结构OJ题】环形链表

    原题链接:https://leetcode.cn/problems/linked-list-cycle/description/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 整体思路: 定义 快慢指针fast,slow ,如果 链表确实有环 , fast指针一定会在环内追上slow指针。 即慢指针一次走一步,快指针一次走两步,两个指针从链表起始位置开始运行,

    2024年02月12日
    浏览(42)
  • 数据结构——图解链表OJ题目

            学完了单链表之后,我们对其基本结构已经有了一定的了解,接下来我们通过一些题目强化对链表的理解,同时学习一些面试笔试题目的新思路以及加强对数据结构单链表的掌握。  目录 题目一.876. 链表的中间结点 - 力扣(LeetCode) 题目二:21. 合并两个有序链表

    2024年02月04日
    浏览(65)
  • 【数据结构OJ题】链表分割

    原题链接:https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8tqId=11004rp=2ru=/activity/ojqru=/ta/cracking-the-coding-interview/question-ranking 目录 1. 题目描述 2. 思路分析 3. 代码实现 整体思路: 创建两个链表 ,分别存放 小于x的结点 和 大于等于x的结点 , 分别进行尾插 。 这道题目使

    2024年02月12日
    浏览(44)
  • 【数据结构】反转链表、链表的中间节点、链表的回文结构(单链表OJ题)

    正如标题所说,本文会图文详细解析三道单链表OJ题,分别为:  反转链表 (简单)  链表的中间节点 (简单)  链表的回文结构 (较难) 把他们放在一起讲的原因是:  反转链表 和  链表的中间节点 是  链表的回文结构 的基础 为什么这样说?请往下看: 目录 1. 反转链

    2024年02月13日
    浏览(72)
  • 【数据结构OJ题】环形链表II

    原题链接:https://leetcode.cn/problems/linked-list-cycle-ii/description/ 如果有小伙伴不了解环形链表,可以先看看这篇文章: https://blog.csdn.net/m0_62531913/article/details/132352203?spm=1001.2014.3001.5502 我们来看下图:  我们根据这个结论就可以做出这道题目了!

    2024年02月12日
    浏览(44)
  • 【数据结构OJ题】移除链表元素

    原题链接:力扣  给你一个链表的头节点  head  和一个整数  val  ,请你删除链表中所有满足  Node.val == val  的节点,并返回 新的头节点  。  方法一:原地删除节点 思路:  首先,定义两个指针:prve和cur。它们会在遍历链表的过程中分别指向当前节点的前一个节点和当前

    2024年02月11日
    浏览(40)
  • 【数据结构】--oj_合并两个有序链表(详解)

    目录 方法一:无头结点的方法  方法二:有头结点的方法 题述: 已给函数头: struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) 已给出链表的结构体定义: struct ListNode {     struct ListNode* next;     int val; }; 已知l1、l2分别指向两个链表 要求: 将两个升序链表合并为一

    2024年02月07日
    浏览(56)
  • 【数据结构OJ题】复制带随机指针的链表

    原题链接:https://leetcode.cn/problems/copy-list-with-random-pointer/description/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 此题可以分三步进行: 1. 拷贝链表的每一个结点,拷贝的结点先链接到被拷贝结点的后面。 2. 复制随机指针的链接:拷贝结点的随机指针指向被拷贝结点随机指针的下

    2024年02月12日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包