C语言每日一题:13《数据结构》环形链表。

题目链接:

一.环形链表运动基础。

使用快慢指针利用相对移动的思想:

1.第一种情况:

1,令快指针(fast)速度为2.

2.慢指针(slow)速度为1.

3.以慢指针进入环中开始。

4。假设slow刚刚进入环中fast与它相距N。

如图所示:

2.第二种情况:

1,令快指针(fast)速度为3.M

2.慢指针(slow)速度为1.

3.以慢指针进入环中开始。

4。假设slow刚刚进入环中fast与它相距M。

如图所示:


3.总结:

我们的距离改变是依靠相对速度而产生的相对距离。当相对速度为1的时候我们只要存在环就一定可以相遇。但是当相对速度为二的时候就相遇考虑之间的距离差值是奇数还是偶数所以判断链表带环的指针速度比较好的是:快指针(fast)速度为2.慢指针(slow)速度为1.

二.带环链表的进入环的节点。

假设:

1.链表无环部分长度:L

2.圆的周长为C

3.慢指针刚刚进入链表是快慢指针的距离为X

1.第一种情况。

1.当我们的环比较大的情况:

如图所示:

2.第二种情况。

2.当我们的环比较小的时候:

如图所示:

总结:环比较短的推导公式是可以通过n的变化适用于各种情况的。

3.两个思路

思路一:

1.依据我们L=(n-1)C+(C-X)作为理论依据。

2.重新定义两个节点一个从交点开始走每次走一步。

3.一个从头链表头开始走两个节点一定会相遇并且相遇的点就是进入点。

c 复制代码
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=fast;
                while(head!=meet)
                {
                    head=head->next;
                    meet=meet->next;
                } 
                return meet;
            }
        }
        return NULL;
       
}

思路二:

1.假设我们没有理论依据。

2.找到节点之后可以转化成相交链表的问题。

3.找到节点之后把相遇节点的下一个置位空。

4.这样就分开了两个链表链表的位节点就是相遇点。

5.求两个链表的长度进行差距长的先走差距步。

6。一起走相等就是交点。

c 复制代码
 struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {

    struct ListNode* curA=headA,*curB=headB;
    struct ListNode* tileA=headA,*tileB=headB;
    int lenA=1,lenB=1;

    while(tileA->next)
    {
        tileA=tileA->next;
        lenA++;
    }
    while(tileB->next)
    {
        tileB=tileB->next;
        lenB++;
    }

    if(tileA!=tileB)
    {
        //说明没有相交
        return NULL;
    }
    
    //说明一定相交
    int gap=abs(lenA-lenB);

    //2.谁比较大就先走差距步
    //假设
    struct ListNode* shortlist=headA,*longlist=headB;
    if(lenB<lenA)
    {
        //修正
        shortlist=headB;
        longlist=headA;
    }

    //长的先走差距补。
    while(gap--)
    {
        longlist=longlist->next;
    }

    while(shortlist&&longlist)
    {
        if(shortlist==longlist)
        {
            return longlist;
        }
        else
        {
            shortlist=shortlist->next;
            longlist=longlist->next;
        }
    }
    return NULL;
}
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;
                struct ListNode* new=meet->next;
                meet->next=NULL;
                return getIntersectionNode(head,new); 
            }
        }
        return NULL;
       
}
相关推荐
程序员老舅6 分钟前
啃透 I2C 驱动开发,才算入门嵌入式 Linux 内核驱动
数据结构·驱动开发·b树·内核·嵌入式·嵌入式开发·i2c
lueluelue4729 分钟前
LeetCode:链表
算法·leetcode·链表
橘子汽水1683 小时前
Leetcode 23,543合并K个升序链表,二叉树的直径
算法·leetcode·链表
2601_955518187 小时前
C语言标准演化史:从K&R到GNU,谁才是正统?
c语言·gnu·标准演化·ansic·性能与可移植性
青山木7 小时前
Hot 100 --- 搜索插入位置
java·数据结构·算法·leetcode
程序员zgh8 小时前
C++ 拷贝赋值运算符 详解
c语言·开发语言·c++
小婷一直在努力10 小时前
自定义类型:联合和枚举
c语言·联合和枚举
夕阳23010 小时前
做耳机开发,需要掌握哪些 C 语言知识?
c语言·开发语言·#蓝牙开发·#蓝牙技术
weixin_4568083810 小时前
【沁恒蓝牙开发】BLE常见错误码与解析
c语言·单片机·嵌入式硬件
Livia要学习11 小时前
Python2和Python3字典底层原理
数据结构