<LeetCode OJ> 141 / 142 Linked List Cycle(I / II)

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?


分析:
假设有环?遍历链表将无法走完,假设无环终会走到尾为NULL的位置
让一个指针每次走一个,一个指针每次走两个位置。
假设当中一个为NULL则无环。
假设相遇(必会相遇)了则有环。

time,o(n),space,o(1)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head==NULL)
            return false;
        ListNode *showNode=head;
        ListNode *fastNode=head;
        while(true)
        {
            if(showNode->next!=NULL)
                showNode=showNode->next;
            else
                return false;
            if(fastNode->next!=NULL && fastNode->next->next!=NULL)    
                fastNode=fastNode->next->next;
            else
                return false;    
            if(showNode==fastNode)
                return true;
        }
        return false;
    }
};


别人的简洁算法:一样的思路

class Solution {
        public:
            bool hasCycle(ListNode *head) {
                ListNode *slow=head,*fast=head;
                while(slow&&fast&&fast->next){
                    slow=slow->next;  //跑的慢
                    fast=fast->next->next;  //跑的快
                    if(slow==fast) return true; //相遇则有环
                }
                return false;
    }
};




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?


分析:


1). 使用快慢指针法,若链表中有环,能够得到两指针的交点M
2). 记链表的头节点为H,环的起点为E

2.1) L1为H到E的距离
2.2) L2为从E出发,首次到达M时的路程
2.3) C为环的周长
2.3) n为快指针在环中所绕圈数


依据L1,L2和C的定义,我们能够得到:
慢指针行进的距离为L1 + L2
快指针行进的距离为L1 + L2 +  n*C

因为快慢指针行进的距离有2倍关系,因此:
2 * (L1+L2) = L1 + L2 +  n*C => L1 + L2 =  n*C => L1 = (n-1)*C+ C - L2
能够推出H到E的距离 = 从M出发绕n-1圈后到达E时的路程
因此,当快慢指针在环中相遇时,我们再令一个慢指针从头节点出发
接下来当两个慢指针相遇时,即为E所在的位置

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *slow=head,*fast=head;  
        while(slow && fast && fast->next){  
            slow=slow->next;  //跑的慢  
            fast=fast->next->next;  //跑的快  
            if(slow==fast) break; //相遇则有环  
        }
        if(fast==NULL || fast->next==NULL)
            return NULL;
        
        fast=head;
        while(slow != fast){  
            slow=slow->next;  //一样的速度跑 
            fast=fast->next; 
        }
        return slow;
    }
};



注:本博文为EbowTang原创,兴许可能继续更新本文。

假设转载。请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/50507131

原作者博客:http://blog.csdn.net/ebowtang

本博客LeetCode题解索引:http://blog.csdn.net/ebowtang/article/details/50668895

posted on 2017-07-25 16:15  slgkaifa  阅读(134)  评论(0编辑  收藏  举报

导航