判断链表是否有环(Floyd 判圈算法/龟兔赛跑算法):
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if (!head || !head->next) return false;
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next) {
slow = slow->next; // 慢指针一次走一步
fast = fast->next->next; // 快指针一次走两步
if (slow == fast) { // 快慢指针相遇,表示有环
return true;
}
}
return false; // 如果快指针到达链表末尾,说明无环
}
};
题目展示
使用快慢指针求链表中点:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* findMiddle(ListNode* head) {
if (!head) return nullptr;
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next) {
slow = slow->next; // 慢指针一次走一步
fast = fast->next->next; // 快指针一次走两步
}
return slow; // 慢指针指向的就是链表的中点
}
};
题目展示
代码说明:
-
判断链表是否有环:
使用快慢指针遍历链表,慢指针每次走一步,快指针每次走两步。如果链表中存在环,快指针最终会追上慢指针(两者相遇),此时我们就可以确定链表中存在环。如果快指针走到了链表末尾(nullptr
),则说明链表无环。 -
求链表中点:
同样使用快慢指针遍历链表,慢指针每次走一步,快指针每次走两步。当快指针走到链表末尾时,慢指针刚好走到链表的中点。