LeetCode Linked List Cycle && Linked List CycleII

本文介绍了如何使用快慢指针法解决链表环问题,包括判断链表是否存在环及找到环的起始节点。通过直观的图形解释了算法原理,并提供了简洁高效的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linked List Cycle:判断一个单链表是否有环,是返回true,不是则返回false。

典型的链表题,这题开始想用两个循环暴力遍历一番求出来,但超时,复杂度不是O(n),看看网上的解答原来可以这样:设置两个指针,一个慢指针,一个快指针,慢的一次走一个,快的走两个,这样如果有环的话,这两个指针必定会在环里开始绕,因为快指针相对于慢指针的速度是1,所以这两个指针必定会在环里的某个节点中相遇,所以只要判断两个是否相等就可以了。

代码:

class Solution {
public:
    bool hasCycle(ListNode *head) {
		if(head == NULL)return false;
		ListNode * slow = head, * fast = head;		
		while(fast != NULL && fast->next != NULL){
			slow = slow->next;
			fast = fast->next->next;
			if(slow == fast)return true;
		}
		return false;
    }
};


Linked List Cycle II:判断一个链表中是否有环,如果有则返回该环的开始节点,没有则返回NULL。这题可以延用上题的思想,同样是快慢指针,我们可以画张图来看一下. 


X为链表首节点,Y为环开始节点,Z为两个指针第一次相遇时的节点,在相遇前,设(a-c) = A, (c-d) = B, (d-c) = C。不考虑绕圈,slow走过的距离为A+B,fast走过的距离为A+B+C+B 因为fast的速度是slow的两倍,所以fast走的距离是slow的两倍,有 2(A+B) = A+B+C+B,可以得到A=C(这个结论很重要!)。所以我们可以在两个指针相遇后, 将fast从X出发, slow从Z出发,两个指针每次走一步,相遇的节点就是Y,即环的开始节点。
代码: 

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(!head)return head;
		ListNode * slow = head;
		ListNode * fast = head;
		while(true){
			if(!fast || !fast->next)return NULL;
			slow = slow->next;
			fast = fast->next->next;
			if(slow == fast)break;
		}
		fast = head;
		while(fast != slow){
			fast = fast->next;
			slow = slow->next;
		}
		return fast;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值