141. 环形链表 简单
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
方法一:哈希表
思路
我们可以通过检查一个结点此前是否被访问过来判断链表是否为环形链表。常用的方法是使用哈希表。
算法
我们遍历所有结点并在哈希表中存储每个结点的引用(或内存地址)。如果当前结点为空结点 null(即已检测到链表尾部的下一个结点),那么我们已经遍历完整个链表,并且该链表不是环形链表。如果当前结点的引用已经存在于哈希表中,那么返回 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) {
std::set<ListNode*> nodeset;//设置集合
while(head){//遍历链表
if(nodeset.find(head) != nodeset.end()){
return true;
}
nodeset.insert(head);
head = head->next;
}
return false;
}
};
方法二:快慢指针(双指针)
/
**
* 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 == nullptr || head->next == nullptr){
return false;
}
ListNode* slow = head;
ListNode* fast = head->next;//fast出发点是slow的下一个点。
while(slow != fast){//此时slow不等于fast,可以进入循环,而且两个点也不可能存在循环
if(fast == nullptr || fast->next == nullptr){//如果fast等于空或者下一个为空,那么说明,到头了
// 如果没有环,快指针会先到达结尾
return false;
}
slow = slow->next;//slow走一步
fast = fast->next->next;//fast走两步
}
return true;
}
};