JZ23 链表中环的入口结点

注意点:

1.首先想到的时快慢指针的,先判断链表是否有环,快指针比慢指针多走两步,如果发现环,让其中一个指针指向头节点,快指针和慢指针都是挪动一步,再次相遇遇到的就是环的入口

2.哈希保存链表每一个节点的地址,如果出现第一个重复的就是环的入口

目录

方法一:快慢指针

方法二:哈希


方法一:快慢指针

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        if(!pHead && !pHead->next) return nullptr;
        //定义快慢指针
        ListNode* fast = pHead;
        ListNode* slow = pHead;
        //快指针走两步,慢指针走一步,这里的条件要注意,不能判断为->next->next
        while(fast && fast->next){
            fast = fast->next->next;
            slow = slow->next;
            //如果相遇,说明有环
            if(fast == slow)
                break;
        }
        //如果快指针走到头,表示没环返回空
        if(fast == nullptr || fast ->next == nullptr)
            return NULL;
        //如果有环,任意一个节点指向头节点
        fast = pHead;
        //找出入环节点,此时快指针和慢指针都走一步
        while(fast != slow){
            fast = fast->next;
            slow = slow->next;
        }
        return fast;
    }
};

方法二:哈希

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        //用哈希保存链表
        unordered_set<ListNode*> set;
        ListNode* p = pHead;
        while(p){
            //判断p是否出现过,如果是,直接返回。
            if(set.count(p))
                return p;
            else
                set.insert(p);
            //向后移动
            p = p->next;
        }
        //无环
        return nullptr;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值