环形链表是一种特殊的链表,其最后一个节点指向链表中的某个节点,从而形成一个环。环形链表可以用来解决一些有环的问题,如判断链表是否有环、找到环的入口等。
在环形链表中,我们可以使用快慢指针来判断是否有环。快指针每次移动两个节点,而慢指针每次移动一个节点,如果存在环,快指针和慢指针最终会相遇。
141判断判断链表中是否有环
CODE
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
using Node = ListNode;
class Solution {
public:
bool hasCycle(ListNode *head) {
if (head == nullptr || head->next == nullptr) {
return false; // 空链表或只有一个节点的链表没有环
}
Node* slow = head;
Node* fast = head;
// 快慢指针找到相遇点
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
return true;
}
}
return false;
}
};
寻找环形链表的入口
找到环的入口可以使用类似于找到两个链表的交点的方法,先让快慢指针相遇,然后将其中一个指针指向链表头,再以相同速度移动两个指针,它们最终会在环的入口处相遇。
要找到环形链表的入口,可以使用快慢指针来解决问题。这个算法被称为Floyd’s Tortoise and Hare algorithm。
步骤如下:
-
使用快慢指针,快指针每次移动两个节点,慢指针每次移动一个节点,直到它们相遇。
-
从头节点和相遇点开始,分别使用两个指针,每次移动一个节点,直到它们相遇。相遇点就是环形链表的入口。
下面是C++代码实现:
Node* findEntry(Node* head) {
if (head == nullptr || head->next == nullptr) {
return nullptr; // 空链表或只有一个节点的链表没有环
}
Node* slow = head;
Node* fast = head;
// 快慢指针找到相遇点
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
break;
}
}
// 没有相遇点,则没有环
if (fast == nullptr || fast->next == nullptr) {
return nullptr;
}
// 从头节点和相遇点开始,分别使用两个指针,每次移动一个节点,直到它们相遇
Node* ptr1 = head;
Node* ptr2 = fast;
while (ptr1 != ptr2) {
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
return ptr1; // 返回环形链表的入口
}
该函数首先检查链表是否为空或只有一个节点。如果是,则没有环,返回空指针。
然后,使用快慢指针找到相遇点。如果没有相遇点,则没有环,返回空指针。
最后,从头节点和相遇点开始,分别使用两个指针,每次移动一个节点,直到它们相遇。相遇点就是环形链表的入口。
CG
-
相遇在人海 聚散在重逢之外