LeetCode 142.环形链表2 C写法

LeetCOde 142.环形链表2 C写法

image-20240713164828368

思路1🤔:

​ 用环形链表的方法,快慢指针找到slow和fast的相遇点,此时头到入口点的位置相遇点到入口点距离一样

​ 我们假设头到入口点的长度为L,环的长度为C,相遇点到入口点的长度为X。那么我们可以计算出在相遇时,fast走了L+n*C+X步(其中n为fast走的圈数),slow走了L+X步,且fast步数是slow的两倍,进一步得出等式 2(L+X) = L+n*C+X,化简后得到L = n*C -X,然而n无论走多少圈,最后还是在相遇点,所以可以把n看做1,最后得L = C - XC-X就是相遇点到入口点的长度,等式成立,推出该方法。

image-20240713171335568

代码🔎:

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(slow == fast) //带环则开始找入口点
        {
            struct ListNode* meet = slow;
            while(meet != head) //meet等于head时代表找到入口点
            {
                meet = meet->next;
                head = head->next;
            }
            return meet;
        }
    }
    return NULL;
}

image-20240713171718872

思路2🤔:

​ 在相遇点用一个指针meet等于slow,meet再找到meet的next,然后将slow->next指向空,那么下一次循环的时候就会在空结点停下,将环形链表变为相交链表

image-20240713173339858

代码🔎:

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while(fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(slow == fast)
        {
            struct ListNode* meet = slow;
            meet = meet->next; 
            slow->next = NULL; //断环
            struct ListNode* List1 = head;
            struct ListNode* List2 = meet;
            int LenHead = 1;
            int LenMeet = 1;
            int gap = 0;
            while(List1->next) //计算走到尾需要多少步
            {
                ++LenHead;
                List1 = List1->next;
            }
            while(List2->next)
            {
                ++LenMeet;
                List2 = List2->next;
            }
            if(List1 == List2) //这里可以不写,因为有相遇点必定是相交链表
            {
                struct ListNode* shortList = head; //先假设头结点到入口点的长度更短
                struct ListNode* longList = meet;
                gap = abs(LenHead-LenMeet); //更长的的先走gap步
                if(LenHead > LenMeet) //如果假设错了就交换
                {
                    shortList = meet;
                    longList = head;
                }
                while(gap--) //让长短链表距离相等
                {
                    longList = longList->next;
                }
                while(longList != shortList) //相等就说明找到入口点
                {
                    longList = longList->next;
                    shortList = shortList->next;
                }
                return longList;
            }
        }
    }
    return NULL;
}

image-20240713175013987

相关推荐

  1. leetcode142.环形II

    2024-07-13 19:28:02       68 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 19:28:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 19:28:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 19:28:02       58 阅读
  4. Python语言-面向对象

    2024-07-13 19:28:02       69 阅读

热门阅读

  1. Android Studio下载与安装

    2024-07-13 19:28:02       16 阅读
  2. 搭建项目时前后端的两个注意事项

    2024-07-13 19:28:02       15 阅读
  3. C语言 错题本

    2024-07-13 19:28:02       22 阅读
  4. 【SQL】MySQL 的死锁问题以及解决方式

    2024-07-13 19:28:02       20 阅读
  5. conda常用命令

    2024-07-13 19:28:02       22 阅读
  6. 卸载docker

    2024-07-13 19:28:02       19 阅读
  7. Redis的一个典型应用

    2024-07-13 19:28:02       16 阅读
  8. Python 列表深度解析:功能强大的数据结构

    2024-07-13 19:28:02       23 阅读
  9. 什么是天使投资

    2024-07-13 19:28:02       20 阅读