【LeetCode & 剑指offer刷题】链表题6:23 有环链表问题-链表中环的入口结点(141. Linked List Cycle)...

【LeetCode & 剑指offer刷题】链表题6:23 有环链表问题-链表中环的入口结点(141. Linked List Cycle)

【LeetCode & 剑指offer 刷题笔记】目录(持续更新中...)

141. Linked List Cycle

Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/*
注意:有可能是中间的小循环
方法:利用两个runner(一个速度为1,一个为2)在list中run,
如果有循环则总会相遇(因为速度差为1),(总存在t使2t-t = kn2,n2为环的长度)
如果没有循环则fast会走到null位置,有循环时不会走到null位置
*/
class Solution
{
public :
    bool hasCycle ( ListNode * head )
    {
        if ( head == nullptr || head -> next == nullptr ) return false ;
        ListNode * fast ,* slow ;
        slow = fast = head ;
       
        while(fast && fast->next) // 如果有环, fast 不可能为 nullptr ,无环时, fast 会运行到末尾 null, 退出循环
        {
            slow = slow -> next ;
            fast = fast -> next -> next ;
            if ( slow == fast )  
                return true ;           
        }
        return false ;      
    }
};
 
 
142 .   Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return   null .
Note:   Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/*
问题:找链表中环的入口(如果不存在环则返回null)
分析:环只能在链表后部
假设有环,无环部分结点数为n1,有环部分结点数为n2, slow指针速度为 1结点/step,fast指针速度为2
    假设经过t个step后相遇,则有 2t - t = n2(fast比slow多经过的结点,可以按路径长度来看), slow继续行进n1个结点就能到环入口
    在设一指针entry于head, 速度也为 1结点/step, 则当entry行进n1个结点也可以到入口,entry与slow会在入口相遇
例子:
head编号0,如果设置prehead,则prehead编号为0,方便分析
 
              ↓--------------←↑
    0 -> 1 ->  2  -> 3 -> 4 ->  5
slow: 0 → 1 → 2 → 3 → 4
fast: 0 → 2 → 4 → 2 → 4
无环部分路径长度2,有环部分路径长度4
相遇后,fast比slow多走了有环部分的路径长度4,故在距起点长度4的结点4处相遇
slow继续行进路径长度2就能走完整个链表即到入口,在开头设置一指针entry,则也行进路径长度2到入口与slow相遇
*/
class Solution
{
public :
    ListNode * detectCycle ( ListNode * head )
    {
        if(head == nullptr || head->next == nullptr) return nullptr;
        ListNode * slow ,* fast , * entry ;
        slow = fast = entry = head ;
       
        while(fast && fast->next) //如果有环,fast不可能为nullptr,无环时,fast会运行到末尾null,退出循环
        {
            slow = slow -> next ;
            fast = fast -> next -> next ;
            if ( slow == fast )  //如果有环,找环入口
            {
                while ( slow != entry )
                {
                    slow = slow -> next ;
                    entry = entry -> next ;
                }
                return slow ;
            }
           
        }
        return nullptr ;
    }
};
 

 

posted @ 2019-01-05 16:54 wikiwen 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值