方法一:快慢指针法
判断一个单链表是否有环的问题。如果一个单向链表不带环,那尾部结点的next指针是NULL,否则尾结点的指针指向链表中的某一结点的数据域。通常可采用快慢指针,定义两个指针,一个指针一次移动一个结点slowP,另一个指针一次移动两个结点fastP,如果两个指针相遇,那么是有环;否则快指针指向NULL,则是无环;第一次相遇时,slowP指向头结点,fastP指向相遇的结点处,每次移动一个结点,直到再次相遇,得到位置。
使用C++和Python实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head==NULL||head->next==NULL)
return NULL;
ListNode* fastP=head;
ListNode* slowP=head;
while(slowP!=NULL&&fastP!=NULL&&fastP->next!=NULL)
{
slowP=slowP->next;
fastP=fastP->next->next;
if(slowP==fastP)
{
ListNode *slowP1=head;
while(slowP1!=slowP)
{
slowP=slowP->next;
slowP1=slowP1->next;
}
return slowP;
}
}
return NULL;
}
};
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def detectCycle(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
slow,fast=head,head
while fast and fast.next:
slow=slow.next
fast=fast.next.next
if slow==fast:
slow=head
while fast!=slow:
fast=fast.next
slow=slow.next
return slow
- 方法二:哈希解法
使用unordered_map记录当前节点是否被访问过,如访问过返回该节点,如到达尾部说明无环。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
unordered_map<ListNode*,bool> visited;
while(head!=NULL)
{
if(visited[head]==true)
return head;
visited[head]=true;
head=head->next;
}
return NULL;
}
};