【力扣】判断环形链表

/*
 * **************************************************************************
 * ********************                                  ********************
 * ********************      COPYRIGHT INFORMATION       ********************
 * ********************                                  ********************
 * **************************************************************************
 *                                                                          *
 *                                   _oo8oo_                                *
 *                                  o8888888o                               *
 *                                  88" . "88                               *
 *                                  (| -_- |)                               *
 *                                  0\  =  /0                               *
 *                                ___/'==='\___                             *
 *                              .' \\|     |// '.                           *
 *                             / \\|||  :  |||// \                          *
 *                            / _||||| -:- |||||_ \                         *
 *                           |   | \\\  -  /// |   |                        *
 *                           | \_|  ''\---/''  |_/ |                        *
 *                           \  .-\__  '-'  __/-.  /                        *
 *                         ___'. .'  /--.--\  '. .'___                      *
 *                      ."" '<  '.___\_<|>_/___.'  >' "".                   *
 *                     | | :  `- \`.:`\ _ /`:.`/ -`  : | |                  *
 *                     \  \ `-.   \_ __\ /__ _/   .-` /  /                  *
 *                 =====`-.____`.___ \_____/ ___.`____.-`=====              *
 *                                   `=---=`                                *
 * **************************************************************************
 * ********************                                  ********************
 * ********************      				             ********************
 * ********************         佛祖保佑 永远无BUG        ********************
 * ********************                                  ********************
 * **************************************************************************
 */

目录

(一)题解:

判断环形链表 

        给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

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

        不允许修改 链表。

示例 1:

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

示例 2:

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

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

提示:

  • 链表中节点的数目范围在范围 [0, 10000] 内
  • -100000 <= Node.val <= 100000
  • pos 的值为 -1 或者链表中的一个有效索引

进阶:你是否可以使用 O(1) 空间解决此题?

(一)题解:

        ——不带环链表:这里不给出不带环链表的情况。

        ——带环链表:画图表示一个带环链表 

 

 

 

        使用快慢指针法:

       创建快慢指针->

        快指针:fast

        慢指针:slow 

        创建快慢指针。由于快指针每次走两步,慢指针每次走一步,所以当快指针走到环起始节点时,慢指针还在环前单链表的半程位置:

        当慢指针进入环时,快指针已经在环中走了一会儿了。

 

        我们设此时快慢指针之间的距离为D(distance),单串链表长度为L,环形链表的周长为C,则另一半优弧的长度为C-D,由于快慢指针都在绕圈,于是这个问题就演变成了追及问题。

(这里暂且把节点数称为长度) 

 

        由于快指针每次走两步,慢指针每次走一步,快慢指针的速度差为1,那么不论D是什么值,每次两指针间的距离减小1,于是距离为D,D-1,D-2,D-3……2,1,0(追上)。

         最终追上:

由于速度差\Deltav是 常数1,1是任何数的因子,所以D一定可以平缓的逐渐减小到0,减小到0就意味着追上了。这样就解释清楚了为什么快2慢1一定可以追上。 

       

 对于整个过程:

slow的路程 = L + X;

fast的路程 = L + n*C + X

得到等式: 

 slow的路程*2=fast的路程->:2*(L+X) = L + n*C + X

化简得:

L = n*C - X

不妨设:n等于1;

L = n - X

         那么,环形链表中剩余的节点数就等于L的节点数,我们就可以在找到相遇节点后用meet指针记录下来,接下来用判断链表相交的方法来找到环的第一个节点:

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode LS;
struct ListNode *detectCycle(struct ListNode *head) {
    LS *fast = head;
    LS *slow = head;
    
    int f = 0;
    while(fast && fast->next)
    {
        fast = fast ->next ->next;
        slow = slow->next;
        if(fast == slow)
        {
            LS* meet = slow;
            while(meet != head)
            {
                meet = meet->next;
                head = head->next;
            }
            return meet;
        }
    }
    return NULL;
}

完~

未经作者同意禁止转载

相关推荐

  1. 100】141.环形

    2024-02-07 14:40:02       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-07 14:40:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-07 14:40:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-07 14:40:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-07 14:40:02       18 阅读

热门阅读

  1. 渗透测试工具库总结(全网最全)

    2024-02-07 14:40:02       45 阅读
  2. redis相关问题

    2024-02-07 14:40:02       27 阅读
  3. UI自动化之Poco常用断言方式

    2024-02-07 14:40:02       30 阅读
  4. 踩坑实录(Second Day)

    2024-02-07 14:40:02       24 阅读
  5. 蓝桥杯(Web大学组)2022国赛真题:新鲜的蔬菜

    2024-02-07 14:40:02       31 阅读
  6. 51单片机 温度传感器得数据,传到上位机

    2024-02-07 14:40:02       32 阅读
  7. docker学习

    2024-02-07 14:40:02       25 阅读
  8. C++类模板实例:数组类封装

    2024-02-07 14:40:02       27 阅读
  9. Synchronized 和 ReentrantLock 的区别

    2024-02-07 14:40:02       39 阅读
  10. Dockerfile和.gitlab-ci.yml文件模板

    2024-02-07 14:40:02       31 阅读
  11. 什么是可解释AI

    2024-02-07 14:40:02       24 阅读
  12. 详解Non-ASCII character ‘\xe6‘

    2024-02-07 14:40:02       30 阅读
  13. Spring Cloud Netflix Eureka的参数调优

    2024-02-07 14:40:02       28 阅读
  14. 融转通与转融通

    2024-02-07 14:40:02       35 阅读
  15. 数据分析之数据预处理、分析建模、可视化

    2024-02-07 14:40:02       28 阅读