原题描述
Linked List Cycle
Given a linked list, determine if it has a cycle in it.
分析
如果链表有环,则从表头开始向后索引时总会回到之前到达过的节点。考虑使用map记录这个节点,然后在向后索引过程中查找map中是否存在这个节点,则可以判断是否存在环。
代码示例
/**
* 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;
if (head->next == head)
return true;
map<ListNode *, bool> record;
ListNode *temp = head;
while(temp->next != NULL)
{
if (record.find(temp) != record.end())
return true;
else
record[temp] = true;
temp = temp->next;
}
return false;
}
};
改进
测试通过后给出的运行时间不太理想,可见算法复杂度可以进一步改进。提示两个指针,可考虑把一个指针回到到过的节点改成两个指针相遇。则可以设一个一次走一步的指针和一个一次走两步的指针,如果有环则两个指针必定会相遇。
改进代码
class Solution {
public:
bool hasCycle(ListNode *head) {
if (head == NULL)
return false;
if (head->next == head)
return true;
ListNode *temp = head;
ListNode *forward = head;
while(temp->next != NULL && forward->next != NULL)
{
temp = temp->next;
forward = forward->next->next;
if (forward == NULL)
return false;
if (temp == forward)
return true;
}
return false;
}
};