142. 环形链表 II【力扣】

212 篇文章 0 订阅
30 篇文章 0 订阅

题意理解

找一个链表中环形的起始结点位置。

问题分析

链表

hash表法

双指针法,快慢指针,每次一步,每次两步。如果快慢指针相遇,说明有环;从相遇点到环开始点的距离和从表头到环开始点的距离相同。

其他

hash表好想好实现,但是空间消耗O(n);双指针法不好想(尤其是找换开始结点),但是空间消耗低O(1).

链接

    ListNode *detectCycle(ListNode *head) {
        ListNode* slow;    //慢指针,每次一步
        ListNode* fast;    //快指针,每次两步
        if (!head || !head -> next || !head -> next -> next)    //判断快指针两步是不是能走
            return NULL;
        fast = head -> next -> next;    //快指针走两步
        slow = head -> next;    //慢指针走一步    必须先走,否则循环判断条件重合
        while (slow != fast)    //如果快、慢指针不等
        {
            if (!fast || !fast -> next)    //判断快指针两步能不能走到
                return NULL;
            slow = slow -> next;    //慢指针走
            fast = fast -> next -> next;    //快指针走
        }
        fast = head;    //快慢指针相等,说明有环;重新利用快指针从头开始走
        while (slow != fast)    //两指针相遇点为环的起始点
        {
            slow = slow -> next;
            fast = fast -> next;
            cout << 2 << endl;
        }
        return slow;
    }

hash表法

    ListNode *detectCycle(ListNode *head) {
        map<ListNode*, int> dict;    //记录每个结点出现的次数
        ListNode* p = head;
        while(p)    //链表不空
        {
            if (dict.find(p) == dict.end())    //字典找不到
            {
                dict[p] ++;    //字典增加这个结点的字典项
            }
            else
            {
                return p;    //找到即为重复
            }
            p = p -> next;    //链表后移
        }
        return NULL;    //链表遍历完,说明没有环
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值