OJ链接:环形链表
- 思路一:快慢指针
我们定义两个指针,初始位置都放在头节点的地方,然后快慢指针一起走,快指针一次走两步(需要注意边界条件),慢指针一次走一步,如果快指针走到nullptr
,该链表就不带环;如果快慢指针相遇,该链表就带环。例如:两个人在操场跑步,一个人的速度是另一个人的两倍,如果跑的快的人追上跑的慢的人,那么快的人必然超过慢的人一圈。那么在链表中,也是一样的。
代码
/**
* 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) {
ListNode* slow=head;
ListNode* fast=head;
do{
if(fast==NULL || fast->next==NULL)
return false;
slow=slow->next;
fast=fast->next->next;
}while(slow != fast);
return true;
}
};
- 思路2:map/unordered_map
遍历所有结点并在map
中存储每个结点的引用(或内存地址)。如果当前结点为空结点 nullptr
(即已检测到链表尾部的下一个结点),那么已经遍历完整个链表,并且该链表不是环形链表。如果当前结点的引用已经存在于map
中,那么返回 true
(即该链表为环形链表)。
代码
/**
* 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;
map<ListNode*,int> mp;
ListNode* cur=head;
while(cur)
{
if(mp.find(cur)!=mp.end())
return true;
else
++mp[cur];
cur=cur->next;
}
return false;
}
};