【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  阅读(176)  评论(0编辑  收藏  举报