1.判断单链表是否带环
给定一个单链表,如果带环返回true,不带环返回false.
这里设了两个指针,快指针一次走两个节点,慢指针一次走一个节点。那么如果两个指针在环里相遇,表明单链表带环,如果fast->next==/NULL表明不带环,fast==NULL表明空链表也返回false.
接口代码如下:
//struct ListNode
//{
// int val;
// struct ListNode *next;
//};
int hasCycle(struct ListNode *head) {
struct ListNode*fast=head;
struct ListNode*slow=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
return 1;
}
}
return 0;
}
为什么快指针走2步,慢指针走1步一定可以相遇
带环情况如下:
由上图我们可以看出,如果见表带环
slow走一个节点,fast走两个节点一定可以在环内相遇
如果快指针每次不是走两个节点,是否还会相遇
我们先假设慢指针每次走一个节点。快指针每次走三个节点。
举几个例子:
2.找入环点
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
经过上面的分析
代码如下:
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode*slow=head;
struct ListNode*fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(fast==slow)
{
struct ListNode*meet=fast;//如果带环,找到相遇点
//一个指针从head走,
//另一个指针从meet走,当两个指针相同时为入环口。
while(meet!=head)
{
meet=meet->next;
head=head->next;
}
return head;
}
}
//不带环
return NULL;
}