Given a linked list, determine if it has a cycle in it.
Follow up: Can you solve it without using extra space?
本题要求判断给定链表中是否存在循环。并且题目要求不要使用extra space,因此,我们就不能保存每一个结点的value,在遍历的时候判断是否是循环。这道题可以通过使用速度不同的pointer进行遍历,若两个pointer相遇则说明存在cycle,若遇到NULL指针,则不存在cycle。
/**
* 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)
return false;
ListNode* l1 = head;
ListNode* l2 = head;
while(true)
{
if (!l1 || !l2)
return false;
l1 = l1->next;
if (!l1)
return false;
l1 = l1->next;
l2= l2->next;
if (l1 == l2)
return true;
}
}
};
iven a linked list, return the node where the cycle begins. If there is no cycle, return null.
Follow up: Can you solve it without using extra space?
本题在上一题的基础上,进一步要求我们给出循环的入口结点,如下图中入口结点为3.
由第一题我们可以判断链表是否存在循环,若存在循环,两个pointer会在结点
/**
* 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) {
if (!head)
return false;
ListNode* l1 = head;
ListNode* l2 = head;
while(true)
{
if (!l1 || !l2)
return NULL;
l1 = l1->next;
if (!l1)
return NULL;
l1 = l1->next;
l2= l2->next;
if (l1 == l2)
break;
}
l1 = head;
while (l1 != l2)
{
l1 = l1->next;
l2 = l2->next;
}
return l1;
}
};
相信运行过上面代码的同学可以发现以上解法确实是正确的,但是这个解法看起来并不是很直观,为了打消同学们的疑虑,下面我将证明上面解法的正确性。
如上图所示的链表,循环外长度设为
假设有两个指针分别为
假设两个指针相遇的位置为
到此我们得到了判断循环存在的证明结果,下面证明获取循环入口结点的解法。
在第一题中两个指针相遇时,前进的步长为循环的长度
但是根据上面的思路我们存在一个问题,我们并不知道
LeetCode (27) Linked List Cycle (判断cycle存在、寻找cycle入口节点)
原文地址:http://blog.csdn.net/angelazy/article/details/45335757