LeetCode链表141. 环形链表
题目描述
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例
一
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
二
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
解法
其实pos对于写代码没有用处,只是便于理解题目
穷举法
使用两个指针,一个指针用于遍历,另一个用于检测;
每当遍历指针前进一步,使用检测指针检测遍历指针是否走到了之前走过的节点
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==NULL||head->next==NULL)
return false;
ListNode* faster=head->next;
ListNode* slower=head;
int count=0;
//记录遍历指针走过的节点数
while(faster!=NULL){
for(int i=count;i>0;i--){
slower=slower->next;
if(slower==faster)
return true;
}
//检测是否成环
faster=faster->next;
slower=head;
//刷新slower,便于下一次的检测
count++;
}
return false;
}
};
快慢指针
操场跑步时,只要时间足够长,两个人同地起跑,快的人一定会追上慢的人。
定义两个指针,快指针一次走两步,慢指针一次走一步,如果成环,快指针追上慢指针。
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode* faster=head;
ListNode* slower=head;
if(head==NULL)
return false;
while(faster!=NULL&&faster->next!=NULL){
faster=faster->next->next;
slower=slower->next;
if(faster==slower)
return true;
}
return false;
}
};
集合法
思路:使用一个集合,每次遍历将节点放入集合,集合具有互异性,每次检测放入后检测集合中元素个数与遍历次数是否相等,如果不相等则成环。
class Solution {
public:
bool hasCycle(ListNode *head) {
set<ListNode*> a;
ListNode* p=head;
int count=0;
while(p!=NULL){
a.insert(p);
if(a.size()==count)
return true;
p=p->next;
count=a.size();
}
return false;
}
};