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;
       
}
相关推荐
轴测君2 小时前
3 无重复字符的最长子串
数据结构·算法·leetcode
小十一再加一2 小时前
【C初阶】动态内存管理
c语言
lifallen12 小时前
Hadoop MapReduce 任务/输入数据 分片 InputSplit 解析
大数据·数据结构·hadoop·分布式·算法
熙xi.12 小时前
数据结构 -- 哈希表和内核链表
数据结构·算法·散列表
Univin14 小时前
8.25作业
数据结构·windows
胡萝卜3.016 小时前
数据结构初阶:详解单链表(一)
数据结构·笔记·学习·单链表
闪电麦坤9517 小时前
数据结构:红黑树(Red-Black Tree)
数据结构··红黑树
墨染点香18 小时前
LeetCode 刷题【53. 最大子数组和】
数据结构·算法·leetcode
NekoCNN18 小时前
现代视角下的线性表全解
数据结构