leetcode:环形链表(详解)

前言:内容包括-题目,代码实现,大致思路,代码解读,拓展问题

题目:

给你一个链表的头节点 head ,判断链表中是否有环。

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

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle
 

代码实现:

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(slow == fast)
        {
            return true;
        }
    }
    return false;
}

大致思路:

1 使用快慢指针遍历链表,slow一次走一步,fast一次走两步,若是遍历能够结束则不是环形链表

   注意:链表结点的个数可为偶数,奇数

   若是偶数个结点,遍历结束的条件是fast为NULL

   若是奇数个结点,遍历结束的条件是fast->next为NULL

2 若是循环不能结束

   fast指针会先进入环形中,slow指针后进入环形中

   当slow指针进入环形后,fast开始追击slow,两个人每行动一次,它们之间的距离会缩小1

   所以fast一定会追上slow,即fast和slow会相遇,这便是有环形链表存在的有利证明

   因为若是没有环形链表,则fast和slow永不会相遇,而正是有了环形链表,fast和slow才会相遇

代码解读:

bool hasCycle(struct ListNode *head) 
{
    struct ListNode *slow = head;
    struct ListNode *fast = head;
    while(fast && fast->next)//遍历链表
    {
        slow = slow->next;//slow一次走一步
        fast = fast->next->next;//fast一次走两步

        if(slow == fast)//存在环形链表,使原本不会相遇的fast和slow会面
        {
            return true;
        }
    }
    return false;//遍历能够结束,不存在环形链表
}

拓展问题:

 1 slow和fast一定会相遇吗?

答:一定会相遇

fast会先进环,slow会后进环,假设当slow进环后,fast和slow之间的距离为N

 

fast开始追击slow,slow一次走一步,fast一次走一步,二者每行动一次,之间的距离缩小1

它们的距离变化如下:

N

N-1

N-2

……

2

1

0

可以看到slow和fast之间的距离最终会缩小至0,即slow和fast相遇了

2 若是slow走一步,fast走3/4/5步,可以相遇吗?

答:不一定相遇

以slow走一步,fast走3步为例

fast会先进环,slow会后进环,假设当slow进环后,fast和slow之间的距离为N

 

fast开始追击slow,slow一次走一步,fast一次走3步,二者每行动一次,之间的距离缩小2

它们的距离变化如下:

当N为2的倍数(偶数)时

N

N-2

N-4

……

2

0

slow和fast会相遇

当N不是2的倍数(奇数)时

N

N-2

N-4

……

3

1

-1

slow和fast会错过,二者会间隔一步

 错过之后进入下一轮追击,fast和slow的距离变成C-1

若是C-1为偶数,slow和fast可以相遇

若是C-1为奇数,slow和fast永远不会相遇

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值