2023-07-30力扣每日一题

文章介绍了如何检测链表中是否存在环,并找出入环的节点。使用的方法包括快慢指针法和哈希映射法。快慢指针法中,通过设置一个指针每次前进两步,另一个指针前进一步,若两者相遇则表明存在环,并可通过新指针重新从头开始,与慢指针同步前进找到入环点。哈希映射法则利用地图记录已访问节点,遇到已访问节点即为环。
摘要由CSDN通过智能技术生成

链接:

142. 环形链表 II

题意:

求链表是否有环,并给出入环的点

解:

哈希关联标记或者快慢指针

快慢指针逻辑:设入环前长度a,快慢相遇时指针在b,环长度为c,fast=2*slow(慢走一步,快走两步)

在这里插入图片描述

那么当相遇时2(a+b)=a+nc+b==>a=nc-b=(n-1)c+c-b(fast已经走了n圈)

如果有新的指针ptr以速度1走完a到达入环位置,则slow在期间移动了(n-1)c+c-b,其中(n-1)c刚好为n-1圈被忽略,b+c-b=c,刚好又走完一圈到达入环节点

所以这时如果ptr和slow相遇,则该节点为入环位置,如果不相遇或者过程中任意一个指针指向空节点则不存在环

主要是数学推导,有点难

实际代码:

#include<bits/stdc++.h>
using namespace std;
struct ListNode
{
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};
ListNode *detectCycle(ListNode *head)//快慢指针 
{
    if(head==nullptr||head->next==nullptr) return nullptr;
    ListNode* fast=head,*slow=head;
    slow=slow->next;fast=slow->next;
    while(slow!=fast&&slow!=nullptr&&fast!=nullptr)//快慢指针相遇 
    {
        slow=slow->next;
        fast=fast->next;
        if(fast!=nullptr) fast=fast->next;
    }
    if(fast==nullptr) return NULL;
    fast=head;//新指针ptr 
    while(slow!=fast&&slow!=nullptr&&fast!=nullptr)//寻找入环点 
    {
        slow=slow->next;
        fast=fast->next;
    }
    if(slow==fast&&slow!=nullptr) return slow;
    return NULL;
}
/*
ListNode *detectCycle(ListNode *head)//哈希map 
{
    unordered_map<ListNode*,bool>book;
    if(head==nullptr) return nullptr;
    while(head!=nullptr)
    {
        if(book.count(head)) return head;
        else book[head]=true;
        head=head->next;
    }
    return nullptr;
}*/
int main()
{
    
}

限制:

  • 链表中节点的数目范围在范围 [0, 104]
  • -105 <= Node.val <= 105
  • pos 的值为 -1 或者链表中的一个有效索引
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值