当前位置: 首页 > article >正文

leetcode第142题:环形链表 ||(C语言+引申问题全解)

思路1(思路难、代码简单):

slow一次走一步,fast一次走两步;相遇时搞个meet,再搞一个head,head和meet一起走,每次走一步;head、meet相遇处,即为结果。

思路解释:

当相遇时,slow走的路程:L+N;当相遇时,fast走的路程L+x*C+N。(x指fast走过的圈数,x>0)

这时,可能有爱发问的读者有了疑惑:slow在1圈以内就能和fast相遇吗?

答:of course。首先,slow和fast肯定能够相遇;若slow和fast相距M,那么随着两指针移动,M不断变小,直到变为0相遇。然后,因为fast的速度是slow是两倍;如果slow走完一圈,此时fast已经走完了两圈,然而slow和fast不会出现错过不能相遇的情况。综上所述,slow肯定能在1圈以内和fast相遇。

因为fast走的路程是slow2倍,故得公式:2*(L+N) = L + x*C + N

化简以后,得 L = x*C - N

当x为1时,meet 和 head 都相距入环的第一个结点 C - N 的距离。

当x>1时,meet相距入环第一个结点 (x-1)*C + C - N,较于上一种情况,只是多转了几圈,并无二致。

代码:

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow=head,*fast=head;
    while(fast && fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;

        if(slow == fast)
        {
            struct ListNode* meet=slow;
            while(meet != head)
            {
                meet = meet->next;
                head = head->next;
            }

            return meet;
        }
    }

    return NULL;
}

思路2(思路简单、代码量比较大):

注:该思路基于思路1

slow、fast相遇后,定义一个newhead,且 newhead = meet->next,然后将meet->next置空。操作执行完毕后,效果如上图所示。

此时,我们就能看到一个Y字型,不难想到相交链表。

(相交链表讲解文章:相交链表讲解)

因此,直接使用相交链表的函数完成操作。

代码:

typedef struct ListNode listnode;
 typedef struct ListNode listnode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    listnode* curA,*curB;
    curA = headA,curB = headB;
    int lenA = 1,lenB = 1;
    while(curA->next)
    {
        curA = curA->next;
        lenA++;
    }
    while(curB->next)
    {
        curB=curB->next;
        lenB++;
    }

    if(curA != curB)
    return NULL;

    int gap = abs(lenA - lenB);
    listnode* longlist = headA,* shortlist = headB;
    if(lenB > lenA)
    {
        longlist = headB;
        shortlist = headA;
    }

    while(gap--)
    {
        longlist = longlist -> next;
    }

    while(longlist != shortlist)
    {
        longlist = longlist->next;
        shortlist = shortlist->next;
    }

    return shortlist;
}
struct ListNode *detectCycle(struct ListNode *head)
{
    listnode* fast=head,*slow=head;
    while(fast && fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow == fast)
        {
            listnode* next = slow->next;
            slow->next=NULL;
            return getIntersectionNode(head,next);
        }
    }
    return NULL;
}


http://www.kler.cn/a/292299.html

相关文章:

  • 面试时问到软件开发原则,我emo了
  • 前端知识点---this的用法 , this动态绑定(Javascript)
  • Hadoop 学习心得
  • CSS 响应式设计之媒体查询技术
  • Qt 日志文件的滚动写入
  • 基于Spring Boot的在线性格测试系统设计与实现(源码+定制+开发)智能性格测试与用户个性分析平台、在线心理测评系统的开发、性格测试与个性数据管理系统
  • ETL数据集成丨SQLServer到Doris的无缝数据同步策略
  • 虚拟机苹果系统MacOS中XCode的安装
  • Spring Boot:医疗排班平台的技术支撑
  • 帆软报表使用url访问报表,自定义前端搜索,优化报表展示
  • 查询数据库版本、查询数据字符集sql
  • 深度学习-用神经网络NN实现足球大小球数据分析软件
  • NAT技术-将多个内部网络设备映射到一个公共IP地址
  • 当小程序遭遇攻击或超出流量峰值时:SCDN边缘加速的高效防护策略!
  • Mysql复杂的查询语句有哪些
  • 这个爬虫工具可以解锁复杂网站,不错~
  • Kafka【九】如何实现数据的幂等性操作
  • 淘宝商品详情API中的优惠券与红包信息解析
  • 《Linux运维总结:基于X86_64+ARM64架构CPU使用docker-compose一键离线部署consul 1.18.1容器版分布式ACL集群》
  • 【专题】2024全球电商消费电子市场研究报告合集PDF分享(附原数据表)
  • Python可视化集大成之作 - Seaborn 介绍
  • 集成电路学习:什么是ROM只读存储器
  • 《中国电化教育》
  • 使用C语言实现字符推箱子游戏
  • 使用Gin框架实现HTTP重定向
  • 使用Redis实现记录访问次数(三种方案)