【OJ】环形链表

目录

  • 1. 环形链表||(142)
    • 1.1 题目描述
    • 1.2 题目分析
    • 1.3 代码
  • 2. 环形链表(141)
    • 2.1 题目描述
    • 2.2 题目分析
    • 2.3 代码

1. 环形链表||(142)

1.1 题目描述

【OJ】环形链表_第1张图片【OJ】环形链表_第2张图片

1.2 题目分析

带环链表:尾节点的next指向链表中的任意节点。
那么环形链表怎么判断链表带不带环?
得考虑哪个节点是环里面的。
我们就会想到如果一个节点位置出现两次,那么就是进环了。但是并不能知道怎么判断位置重复出现。什么时候进环,又不知道。

这里用快慢指针最合适。
【OJ】环形链表_第3张图片
当两个指针都进入环以后,slow开始追击fast,到某一个位置会相遇。
只有两个指针都进入环才会相遇。
【OJ】环形链表_第4张图片
假设将起点到入环口点距离记为L,入口点到相遇点的位置记为X,环的长度记为C。
从开始位置相遇时slow走的距离是L+X,从开始点相遇时到fast走的距离是L+n*C+X。因为不知道在slow进环之前,fast已经在环里转了多少圈了,就设为n。
【OJ】环形链表_第5张图片
结论:一个指针从相遇点开始走,一个指针从头开始,它们会在入口点相遇。

1.3 代码

struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode *slow,*fast;
    slow=fast=head;

    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;

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

    return NULL;
}

【OJ】环形链表_第6张图片

2. 环形链表(141)

2.1 题目描述

【OJ】环形链表_第7张图片
【OJ】环形链表_第8张图片

2.2 题目分析

与上一题类似,也使用快慢指针,不同的是这里不需要找出相遇点的位置,只需要判断是不是有环就行。
如果slow走一步fast走2步一定会相遇,为什么呢?
slow进环后,fast和slow的距离每次追击都会缩减1。
假设slow进环时,fast与slow之间的距离为N。
【OJ】环形链表_第9张图片
在这里插入图片描述
如果slow一次走一步,fast一次走3步一定会相遇吗?
此时距离变化就是:这里就得分情况了
【OJ】环形链表_第10张图片
总之;

  1. 如果N是偶数直接就追上了。
  2. 如果N是奇数,C是偶数,永远追不上。
  3. 如果N是奇数,C是奇数,第一轮错过了,第二轮就追上了。
    在这里插入图片描述
    如果slow一次走n步,fast一次走m步,一定会相遇吗?(m>n>1)
    这时缩小的距离是m-n,如果满足N%(m-n)==0就能追上。

2.3 代码

bool hasCycle(struct ListNode *head) {
    struct ListNode *slow,*fast;
    slow=fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            return true;
        }
    }
    return false;
}

【OJ】环形链表_第11张图片
有问题请指出,大家一起进步!

你可能感兴趣的:(OJ题,链表,数据结构,笔记)