题目
Given a linked list, determine if it has a cycle in it.
To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the second node.
分析
- 判断链表有没有环的一个基本做法是用快慢指针,当快指针和慢指针重合的时候,说明有环,否则没有环。
- 快指针每次走两步,慢指针每次走一步,只要有环一定能重合。就像沿着环形操场跑步,跑的快的一定能超过跑得慢的。
代码和注释
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
struct ListNode ret, *p, *q; //定义虚拟头节点和两个指针
ret.next = head; //虚拟头节点指向真正的头节点
p = q = &ret; //两个指针初始都指向虚拟头节点
do {
p = p->next;//由于p,q初始指向ret,一定不为null,所以有next属性
q = q->next;//慢指针p走一步,快指针q走两步
if (q) { //如果q为null,不能执行下一步,并且直接跳出while循环,return fasle
q = q->next;
}
}while(p != q && q); //当p == q且q不为空的时候,可以判断有环
if (q) return true;
return false;
}