给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
思路:
①可以使用双指针法,举个栗子:在一个环形跑道上,A的速度为单位1,B的速度为单位2,那么两者从跑道的任意地方同向同时开跑,那么总有两者相遇的时候(暂时不考虑起始位置一样),所以设置slow指针和fast指针来解决这个问题
②也可以使用map去标记,每个结点的键值都记录下来,只要是个环,那么键值一定会出现相同,这个时候就可以判定出现环
#include<iostream>
#include<cstdlib>
#include<map>
using namespace std;
typedef struct ListNode
{
int val;
ListNode *next;
} ListNode,*PtrToNode;
void Print(PtrToNode N)
{
PtrToNode p = N;
while(p!=NULL)
{
printf("%d ",p->val);
p = p->next;
}
printf("\n");
return;
}
PtrToNode Insert(PtrToNode N,int e)
{
PtrToNode p = (PtrToNode)malloc(sizeof(ListNode));
p->val = e;
p->next = NULL;
if(N == NULL)
{
N = p;
}
else
{
PtrToNode q = N;
while(q->next != NULL)
{
q = q->next;
}
q->next = p;
}
return N;
}
class Solution
{
public:
bool hasCycle(ListNode *head)
{
if(head == NULL)
return false;
ListNode *slow = head,*fast = head->next;
if(slow==NULL || fast==NULL)
return false;
while(fast!=NULL && fast->next!=NULL)
{
if(slow == fast)
return true;
slow = slow->next;
fast = fast->next->next;
}
return false;
}
};
//class Solution
//{
//public:
// bool hasCycle(ListNode *head)
// {
// if(head == NULL)
// return false;
// map<ListNode*,int>M;
// ListNode *p = head;
// while(p!=NULL)
// {
// M[p]++;
// if(M[p]>1)
// return true;
//
// p = p->next;
// }
// return false;
// }
//};
int main()
{
Solution s;
PtrToNode N,temp;
N = NULL;
N = Insert(N,1);
N = Insert(N,2);
temp = N->next;
N = Insert(N,3);
N = Insert(N,4);
N = Insert(N,5);
N = Insert(N,6);
PtrToNode p = N,q;
while(p!=NULL)
{
q = p;
p = p->next;
}
q->next = temp;
// Print(N);
if(s.hasCycle(N))
printf("TRUE\n");
else
printf("FALSE\n");
return 0;
}