判断单链表中是否存在环
1、使用快慢指针
慢指针每次移动一个结点,快指针每次移动两个结点,快指针移动的快,必将先进入环,待慢指针移动进环内,就有点像追及问题了,快指针移动的快,当 p1 == p2 时,就说明快慢指针相遇了,即链表有环。懒得画图,就描述一下算了。。。
bool hasCycle(ListNode *head) {
if(head == null)
return false;
ListNode *p1 = head,*p2=head;
while(p2!= nullptr && p2->next != nullptr )
{ // 如果p2遇到NULL,则说明链表没有环
p1 = p1->next; // 慢指针
p2 = p2->next->next; // 块指针
if(p1 == p2)
{
return true;
}
}
return false;
}
2、利用set容器
bool hasCycle(ListNode *head)
{
if(head == nullptr)
return false;
set<ListNode*> s;
while(head) // head != nullptr
{
if( s.count(head) )
return true;
// 如果该节点不在容器,就插入该节点
s.insert(head);
head = head->next;
}
return false;
}
3、使用一个公共结点,遍历结点,使next指向公共结点,后移相关指针,继续遍历,如果此时某个结点的next指向这个公共结点,说明这个结点就是环的入口,即链表有环。
bool hasCycle(ListNode *head)
{
ListNode *temp = new ListNode(0); //初始化一个节点值为0的空节点;
if(head == NULL)
return false;
while(head){
if(head->next == temp)
return true;
ListNode *p = head;
head = head->next;
p->next = temp;
}
return false;
}