环形链表

环形链表类


问题描述

在一个单向链表中,链表的尾结点指向链表的一个节点(这个节点可以是链表的任意一个节点,包括头结点和尾结点),形成闭环,称为环形链表。
例如:
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、判断链表是否带环?

提示:
(1)如果直接对环形链表遍历,则会造成死循环。
(2)可以考虑使用快慢指针,由于步长不同快慢指针总会相遇。

代码如下(示例):

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode *slow,*fast;
    slow=fast=head;

    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;

        if(slow==fast)//slow==fast说明相遇,为环形链表
        return true;
    }

    if(fast==NULL||fast->next==NULL)//fast为NULL说明,遍历到了尾结点
    {
        return false;
    }  
}

二、判断链表换开始的起点

1.题目分析

(1)快慢指针的步长差距只能为1;
分析:如果步长差距不为1,为2或者其他,由于链表环内的元素个数的原因,步长过大,会增加时间复杂度。

(2)假设起始位置到链表起点的距离为L,环长为C,相遇点距环起点的距离为X。fast指针走的长度为2*(L+X+mC);slow指针走的距离为L+X+nC;(这里可以类比为物理的追及问题,时间为fast走的节点数L+X+mC)
快慢指针的路程相等,即2
(L+X+mC)=L+X+nC,得到L+X=K*C,K=2m-n;

2.代码编写

代码如下(示例):

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode *slow,*fast;
    slow=fast=head;

    while(fast&&fast->next) //判断是否带环
    {
        slow=slow->next;
        fast=fast->next->next;

        if(slow==fast)
        break;

    }

    if(fast==NULL||fast->next==NULL)
    return NULL;

    struct ListNode *meet=fast;//相遇根据推论编写程序
    while(meet!=head)//L+X=K* C
    {
        head=head->next;
        meet=meet->next;
    }
    return meet;

}

总结

环形链表由于自身结构尾部相连的原因,只能使用快慢指针来判断链表是否存在环形结构,同时还需数学推论来支撑程序的算法结构。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值