剑指offer-链表中环的入口结点(C++ map 环节点)

链表中环的入口结点

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

题解:
1)利用辅助空间map,来一个陌生结点,则存入map,当链表有尾节点时,则不含有环。若含有环,则第一个遇见的存在map中的结点,则是环的入环结点。
代码如下:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        map<ListNode*,int> node;
        if(!pHead) return NULL;
        while(pHead){
            if(node.find(pHead)!=node.end())
                return pHead;
            else{
                node[pHead]=1;
                pHead=pHead->next;
            }
        }
        return NULL;
    }
};

2)环节点
若链表中有环,则链表没有尾指针,同时,如果有链表的环节点个数,则可以利用快慢指针进行遍历。若环有4个节点,则让快指针先前进4个节点,然后快慢指针同时前进,则当慢指针指向环的入口结点时,快指针也同时指向环的入口结点。
代码如下:

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* meetingnode(ListNode* pHead){
        ListNode* slow=pHead;
        if(!slow->next) return NULL;
        ListNode* fast=slow->next;
        while(slow&&fast){
            if(slow==fast)
                return slow;
            slow=slow->next;
            fast=fast->next;
            if(fast)
                fast=fast->next;
        }
        return NULL;
    }
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        /*map<ListNode*,int> node;
        if(!pHead) return NULL;
        while(pHead){
            if(node.find(pHead)!=node.end())
                return pHead;
            else{
                node[pHead]=1;
                pHead=pHead->next;
            }
        }
        return NULL;*/
        if(!pHead) return NULL;
        ListNode* meetnode=meetingnode(pHead);
        if(!meetnode)
            return NULL;
        ListNode* p=meetnode;
        ListNode* slow=pHead;
        ListNode* fast=pHead->next;
        while(p->next!=meetnode){
            p=p->next;
            fast=fast->next;
        }
        while(slow!=fast){
            slow=slow->next;
            fast=fast->next;
        }
        return fast;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值