给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
解题思路:
1.我们创建俩个指针:快指针fast , 慢指针slow。
2.让慢指针每次走一步,快指针每次走俩步。
slow = slow->next;
fast = fast->next->next;
3.如果有环快指针就会追上慢指针。
代码实现
/**
* 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) {
//设置快慢指针slow,fast
ListNode* slow = head,*fast = head;
while(fast && fast->next)
{
slow = slow->next;//慢指针每次走一步
fast = fast->next->next;//快指针每次走俩步
if(fast == slow)
{
return true;
}
}
return false;
}
};
看到这里可能会有人有疑问,为什么快指针走俩步就能追上呢?如果走3步,4步或者n步是否可以追上呢?
我的回答是:3步4步或者n步可能会追上,但也可能追不上,会一直循环下去。
接下来给大家解析一波:
假设慢指针进入循环时,fast与slow的距离为x,
fast和slow每走一次,他俩之间的距离就缩小一步 。
变成x-1,x-2,x-3,···直到x减到0相遇。
如果fast走3步,距离x就为
x-2,x-4,···
当x为奇数时,fast会跳过slow,不会相遇。跳过以后差距还是奇数,会导致死循环。
走N步类似,也会死循环。