2023-07-30力扣每日一题

链接:

142. 环形链表 II

题意:

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

解:

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

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

2023-07-30力扣每日一题_第1张图片

那么当相遇时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
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_mapbook;
    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 或者链表中的一个有效索引

你可能感兴趣的:(力扣每日一题,leetcode,算法,链表)