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

发布于:2024-05-03 ⋅ 阅读:(26) ⋅ 点赞:(0)

🎁个人主页:我们的五年

🔍系列专栏:数据结构

🌷追光的人,终会万丈光芒

 

 前言:

链表的带环问题在链表中是一类比较难的问题,它对我们的思维有一个比较高的要求,但是这一类问题分析起来也是很有趣的,下面我就给大家讲一下链表的带环问题,并且带上几个例题进行分析。

喜欢的铁子们可以点点关注,感谢大家的支持。

🏝1.链表的分类:

●根据链表,单向,双向,带头,不带头,循环,不循环,可以把链表分成八种。虽然说有八种链表,但是常用的只有:不带头单向不循环链表,带头双向循环链表。

●但是今天我们要看的是不带头单向不循环,但是内部带环的问题。

🏝2.判断链表是否带环?

【LeetCode】第141题-链接:https://leetcode.cn/problems/linked-list-cycle/description/

 🏜问题描述:

 

 🏜实现代码:

/**

 * Definition for singly-linked list.

 * struct ListNode {

 *     int val;

 *     struct ListNode *next;

 * };

 */

 typedef struct ListNode ListNode;

bool hasCycle(struct ListNode *head) {

    ListNode* fast=head;

    ListNode* slow=head;

    while(fast&&fast->next)

    {

        fast=fast->next->next;

        slow=slow->next;

        if(fast==slow)

            return true;

    }

    return false;

}

🏜问题分析:

1.快慢指针都从头开始走,慢指针一次走一步,快指针一次走两步。

2.当fast进环的时候,slow还在环外。

3.当slow金环的时候,fast在环中的某个位置。也就是说,fast和slow差了N个位置,当fast和slow都进环的时候,就变成了追击问题。

4.slow每次走一步,fast每次走两步,也就是fast去追slow,把slow看成静止的,fast就一次往前面走一步,所以fast一定可以追上slow。

🏝3.如果fast一次走三步,slow一次走一步,一定可以追上吗?

这里先给出答案:一定可以追上!

当slow刚刚进环的时候,fast在环的某个位置,此时fast开始追击slow,还是把slow看成静止的,fast每次往相对于slow追击两步。

开始时,slow与fast相差N

1.当N为偶数时:

因为每次fast走三步,slow走一步。也就是N每次-2。因为N为偶数,所以是一定可以追上的。

2.当N为奇数,环的周长为C为奇数:

因为N每次都是-2,所以第一次追的时候fast和slow会错过,fast比slow快出了一步。

此时环的周长C为奇数,那么此时fast和slow相差为C-1为偶数,那么就回到第一种情况。

3.N为奇数,C为偶数,根据情况2,fast追完一圈,fast和slow相差的距离为奇数,所以fast和slow会一直错过,但是这种情况真的存在吗?

先来看看这个等式:

slow刚刚进环时:

slow走过的路程为:L

fast走过的路程为:L+k*C+C-N

因为fast的速度是slow的三倍,所以有3*L=L+k*C+C-N。

2*L=k*C+C-N

等式左边:偶数

等式右边:情况3时的情况是:C为偶数,N为奇数,k*C为偶数,C-N为奇数,所以等式右边为奇数

所以这种情况是不存在的!!!

代码分析:fast一次走三步,slow一次走一步

 typedef struct ListNode ListNode;

bool hasCycle(struct ListNode *head) {

    ListNode* fast=head;

    ListNode* slow=head;

    while(fast&&fast->next&&fast->next->next)

    {

        fast=fast->next->next->next;

        slow=slow->next;

        if(fast==slow)

            return true;

    }

    return false;

}

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


网站公告

今日签到

点亮在社区的每一天
去签到