题目描述
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0
开始)。 如果 pos 是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true
。 否则,返回 false
。
示例
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
提示
链表中节点的数目范围是 [0, 104]
-105 <= Node.val <= 105
pos 为 -1 或者链表中的一个 有效索引 。
解题想法
这道题在leetcode上属于简单题,但由于第一次遇见这种解法(也由于第一次想错了,根本不是正解)所以就想记录一下。
很明显题目要判断链表中是否有环,于是可以想到如果在链表中有两个指针分别向前跑,当两个指针指向的结点相同的时候便证明链表中有环存在。这个时候就需要一个循环来判断两个指针是否相等。此时条件应该是first != second
因此如果我们初始化两个指针在同一个位置,那么将无法进入循环,因此需要将两个指针分别初始化在头结点以及头结点的下一个结点,还要注意的是,first
指针的速度应该要快于second
指针的速度,这样,当链表中有环时,first
指针会先进入环中,并一直在环中循环,而当second
指针进入环时,由于first
指针速度快,将会在某个循环时刻追上second
指针,这样当两个指针重合后就能够判断出链表存在环,下面附上C++代码
/**
* 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 (head == nullptr || head->next == nullptr) {
return false;
}
ListNode *first = head->next;
ListNode *second = head;
while (first != second) {
if (first == nullptr || first->next == nullptr) {
return false;
}
second = second->next;
first = first->next->next;
}
return true;
}
};