环形链表——双指针

原题在这里

概述题意:

  给定一个可能有环的链表,如果有环则返回第一个环节点,否则null

低配hash处理:

复制代码
class Solution
{
    map<ListNode *, int> mp;

public:
    ListNode *detectCycle(ListNode *head)
    {
        if (!head || mp[head] == 1)
            return head;
        mp[head] = 1;
        return detectCycle(head->next);
    }
};
map or set
复制代码

高配双指针:

复制代码
class Solution
{
public:
    ListNode *detectCycle(ListNode *head)
    {
        ListNode *p = head, *q = head;
        while (p != nullptr)
        {
            q = q->next;
            if (p->next == nullptr)
                return nullptr;
            p = p->next->next;
            if (p == q)
            {
                //重新走一遍
                p = head;
                while (p != q)
                {
                    p = p->next;
                    q = q->next;
                }
                return p;
            }
        }
        return nullptr;
    }
};
复制代码

analyse:

参考:https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/

大概:

  s快=s慢+n*b,s快=s慢*2,故得:s慢=n*b

如果有环,快指针与慢指针相遇时候,快指针一定比慢指针多走n倍环的长度b,又有快指针路径是慢指针两倍,所得慢指针当前路径为n倍环长度。

继续:

  从此点开始,用两指针分别从头和快慢指针相遇节点开始走,相遇的节点即为入环节点。

  也即s1=0,s2=n*b,那么走非环路径a后即有,s1=a,s2=a+n*b,两者相遇在入环节点。

code:

 

复制代码
struct ListNode
{
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
class Solution
{
public:
    ListNode *detectCycle(ListNode *head)
    {
        ListNode *p = head, *q = head;
        while (p != nullptr)
        {
            q = q->next;
            if (p->next == nullptr)
                return nullptr;
            p = p->next->next;
            if (p == q)
            {
                //重新走一遍
                p = head;
                while (p != q)
                {
                    p = p->next;
                    q = q->next;
                }
                return p;
            }
        }
        return nullptr;
    }
};
复制代码

 

 

 

【Over】

posted @   Renhr  阅读(29)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示