即慢指针一次走一步,快指针一次走两步,两个指针从链表起始位置开始运行,如果链表带环则一定会在环中相遇,否则快指针率先走到链表的末尾。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head)
{
ListNode* fast , *slow;
fast = slow = head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
return true;
}
return false;
}
【扩展问题】 为什么快指针每次走两步,慢指针走一步可以解决问题?
如果链表不带环,两个指针一定不会相遇,因为fast = 2slow 假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。 当慢指针刚进环时,可能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度-1。 此时,两个指针每移动 一次,之间的距离就缩小一步。因此,在慢指针走到一圈之前, 快指针肯定是可以追上慢指针的,即相遇。
【扩展问题】快指针一次走3步,走4步,...n步行吗?
假设快指针一次走3步,慢指针一次走1步
同理可证,快指针走4,5……也行
相遇时,slow指针与fast指针走的路程
head指针走L步,meet指针走C-N步,head指针和meet指针相遇,此时就是环的第一个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* detectCycle(struct ListNode* head) {
struct ListNode *slow = head, *fast = head;
while (fast != NULL && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow) {
struct ListNode *ptr = head, *meet = slow;
while (ptr != meet) {
ptr = ptr->next;
meet = meet->next;
}
return ptr;
}
}
return NULL;
}
一键三连~
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有