一、题目
二、解法
1、哈希表
可以遍历节点并存入哈希表中,同时检测哈希表中是否有重复节点,即转化为检测重复元素的问题,由于只需要key,因此使用C++的unordered_set或者python的set。
unordered_set的简单介绍:
unordered_set<type> set是一种哈希表,可看做集合,只有key元素,没有value元素,因此内部元素不会重复,此外元素只能插入或者删除,不能被修改。一些常用方法如下:
- set.empty(): 判断set是否为空
- set.size(): 元素个数
- set.find(key): 返回指向key的迭代器,若不存在key,返回指向最后元素的迭代器set.end(),因此可用于判断key是否存在
- set.begin()/set.end(): 指向第一个/最后一个元素的迭代器
- set.count(key): 返回key的个数,key存在,返回1;不存在,返回0,也可用于判断key是否存在
- set.insert(key): 尾部插入key元素
- set.emplace(key): 同上
- set.erase(key): 删除key元素
- set.clear(): 清空set
/**
* 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) {
//哈希表
unordered_set<ListNode*> list_set;
while (head != NULL){
if (list_set.count(head)){
return true;
}
list_set.emplace(head);
head = head->next;
}
return false;
}
};
2、快慢指针
定义两个指针,快/慢指针,快指针每次移动两个节点,慢指针每次移动一个节点。初始时,慢指针在位置 head,而快指针在位置 head->next,如果为环形链表,那么在进入环之后快指针一定会追上慢指针,即两个指针相同;否则,快指针会先到尾结点。
/**
* 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;
while (slow != fast){
// 注意遍历到尾节点时,它的指针域为null,
// fast->next==nullptr是为了避免fast->next->next发生错误
if (fast==nullptr || fast->next==nullptr){
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return true;
}
};
参考:https://leetcode.cn/problems/linked-list-cycle/solution/huan-xing-lian-biao-by-leetcode-solution/