其实本题解报告已经在我 Blog 的双指针算法介绍中出现精华内容,https://blog.csdn.net/justidle/article/details/106297779。
LeetCode中国,https://leetcode-cn.com/problems/linked-list-cycle/。
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
你能用 O(1)(即,常量)内存解决此问题吗?
LeetCode 给出本题难度简单。是学习数据结构链表的基础题目。
我们可以通过双指针中的快慢指针来实现。
由于是经典题目,我们用图示来分析两个样例数据,一个有环,一个无环,解释快慢指针如何实现。
1、初始状态。如下图所示,慢指针(slow)和快指针(fast)指向第一个元素。
2、由于快指针(fast)没有到最后。我们将慢指针(slow)向后移动一位,快指针(fast)向后移动两位。如下图所示。
3、由于慢指针(slow)和快指针(fast)不相等,或者快指针(fast)没有到最后。我们将慢指针(slow)向后移动一位,快指针(fast)向后移动两位。如下图所示。
4、由于慢指针(slow)和快指针(fast)不相等,或者快指针(fast)没有到最后。我们将慢指针(slow)向后移动一位,快指针(fast)向后移动两位。如下图所示。
5、如上图所示,慢指针(slow)和快指针(fast)相等,说明有环。
1、初始状态。如下图所示,慢指针(slow)和快指针(fast)都指向第一个元素。
2、由于快指针(fast)没有到最后。我们将慢指针(slow)向后移动一位,快指针(fast)向后移动两位。如下图所示。
3、由于慢指针(slow)和快指针(fast)不相等,或者快指针(fast)没有到最后。我们将慢指针(slow)向后移动一位,快指针(fast)向后移动两位。如下图所示。
4、由于慢指针(slow)和快指针(fast)不相等,或者快指针(fast)没有到最后。我们将慢指针(slow)向后移动一位,快指针(fast)向后移动两位。如下图所示。
5、如上图所示,快指针(fast)已经到了链表的最后,链表的最后是用 NULL 来表示的。这样说明该链表无环。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
//特例判断
if (NULL==head) {
return false;
}
ListNode *slow = head;//慢指针
ListNode *fast = head;//快指针
while (NULL!=fast && NULL!=fast->next && NULL!=fast->next->next) {
//修改位置
slow = slow->next;
fast = fast->next->next;
//判断有环
if (slow==fast) {
return true;
}
}
//无环
return false;
}
};