首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【OJ】环形链表

【OJ】环形链表

作者头像
zxctscl
发布2024-01-23 08:57:24
发布2024-01-23 08:57:24
4370
举报
文章被收录于专栏:zxctscl个人专栏zxctscl个人专栏

1. 环形链表||(142)

1.1 题目描述

1.2 题目分析

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

这里用快慢指针最合适。

当两个指针都进入环以后,slow开始追击fast,到某一个位置会相遇。 只有两个指针都进入环才会相遇。

假设将起点到入环口点距离记为L,入口点到相遇点的位置记为X,环的长度记为C。 从开始位置相遇时slow走的距离是L+X,从开始点相遇时到fast走的距离是L+n*C+X。因为不知道在slow进环之前,fast已经在环里转了多少圈了,就设为n。

结论:一个指针从相遇点开始走,一个指针从头开始,它们会在入口点相遇。

1.3 代码

代码语言:javascript
复制
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;
}

2. 环形链表(141)

2.1 题目描述

2.2 题目分析

与上一题类似,也使用快慢指针,不同的是这里不需要找出相遇点的位置,只需要判断是不是有环就行。 如果slow走一步fast走2步一定会相遇,为什么呢? slow进环后,fast和slow的距离每次追击都会缩减1。 假设slow进环时,fast与slow之间的距离为N。

如果slow一次走一步,fast一次走3步一定会相遇吗? 此时距离变化就是:这里就得分情况了

总之;

  1. 如果N是偶数直接就追上了。
  2. 如果N是奇数,C是偶数,永远追不上。
  3. 如果N是奇数,C是奇数,第一轮错过了,第二轮就追上了。

如果slow一次走n步,fast一次走m步,一定会相遇吗?(m>n>1) 这时缩小的距离是m-n,如果满足N%(m-n)==0就能追上。

2.3 代码

代码语言:javascript
复制
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;
}

有问题请指出,大家一起进步!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 1. 环形链表||(142)
    • 1.1 题目描述
    • 1.2 题目分析
    • 1.3 代码
  • 2. 环形链表(141)
    • 2.1 题目描述
    • 2.2 题目分析
    • 2.3 代码
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档