[lintcode] 103. 带环链表 II [Hard]

描述

给定一个链表,如果链表中存在环,则返回到链表中环的起始节点,如果没有环,返回null。

 

样例

给出 -21->10->4->5, tail connects to node index 1,返回10

挑战

不使用额外的空间

 

思路

第一反应是用一个map<ListNode, bool> visited解决问题。一跑发现TLE。我感觉应该其实应该是因为内存限制。

第二反应:把经过的点统一地改成int infty 1 << 30。 结果成功了,打败了94.6%的提交。感觉是测试数据不够足。没有考虑超大测试数据的原因。

因为通过了就直接在网上搜了答案。然后打开了新世界的大门,解锁快慢指针。

快指针每次跳两步,慢指针每次跳一步。按照 快2慢1 快4慢2 ...的顺序进行。你可能会问问什么有环情况下两个指针一定会遇到呢?这是因为两个指针会遇到一定是 快指针跳的次数 - 慢指针跳的次数 = 环的长度。而按照快指针每次加2慢指针每次加1,快指针会比慢指针快1、2、3、4...所以一定能枚举出环的长度。

第二是如何找到起点呢? 

这里可以知道 在遇到的地方是 F = Meet+Circle ,S = Meet。又有F = 2*S,则 Circle = Meet。 所以遇到的位置其实是这张图名义上的中点。 可以想象把整个环拉直,那么从起点每走一个Circle的长度就到了Meet的位置,每走一个Circle的长度就到了Meet的位置。因此Meet和Head是等价的,并且Meet和Head到Start的距离是相等的。

代码:

class Solution {
public:
    /*
     * @param head: The first node of linked list.
     * @return: The node where the cycle begins. if there is no cycle, return null
     */
    ListNode * detectCycle(ListNode * head) {
        // write your code here
        
        if(head == NULL || head->next == NULL)
        {
            return NULL;
        }
        
        ListNode* fast = head;
        ListNode* slow = head;
    
        
        while(fast != NULL && fast->next != NULL)
        {
            fast = fast->next->next;
            slow = slow->next;
            
            if(fast == slow)
            {
                break;
            }
            
        }
        

        if(fast != NULL && fast == slow)
        {
            fast = head;
            while(fast != slow)
            {
                fast = fast->next;
                slow = slow->next;
            }
            return fast;
        }
        
        
        return NULL;
  
    }

p.s: 注意特殊情况:head是NULL和head->next是NULL。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值