leetcode 环形链表Ⅰ&Ⅱ
1.环形链表Ⅰ
1.1 题目描述
示例
进阶和提示:
1.1.1 接口函数
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
}
1.2 大致框架
1.2.1 想法思路
先要搞清楚什么是带环链表,即原链表的尾可能指向任何一个包含自己的节点
方法是用快慢指针,只要是一个环的话,只要有一个快指针和有一个慢指针,总会在某一个点相遇
1.2.2 具体步骤
实现一个快慢指针,放入循环,只要相等就说明是环
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
1.3 整体实现
bool hasCycle(struct ListNode *head) {
struct ListNode*slow=head,*fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
return false;
}
小结:
这道题只是一个初级阶段,所以解决起来很简单
但是面对下面三个问题你会如何解答?
- 不会当slow进入环之后,本质上就是一个追及问题,fast与slow距离应该是越走越小
- 不一定,本质上和第一题道理逻辑是一样的
总结一下就是在fast一次走三步的情况下, 如果slow进环时,slow跟fast差距N是奇数,且环的长度时是偶数,那么就永远也追不上
所以这个题目是不能乱设置fast的速度的
由于快指针走的路程是慢指针的二倍,所以有一个等式:
2 ∗ ( L + X ) = L + C + X 2*(L+X)=L+C+X 2∗(L+X)=L+C+X
然而这样的推论是错误的,因为我们忽略了fast指针的可能性没错slow确实只会走一圈以内的路程,fast就会追上slow,所以slow走的距离是L+X
然而fast并不一定是只走了一圈,完全可能在里面走了N圈所以快指针应该是走了
2 ∗ ( L + X ) = L + N ∗ C + X 2*(L+X)=L+N*C+X 2∗(L+X)=L+N∗C+X
所以化简等式之后应该是
L = N ∗ C − X L=N*C-X L=N∗C−X {N*C-X}
由之前的结论我们来做下面来一道升级版的题目就会有思路
2. 环形链表Ⅱ
2.1 题目描述
示例
进阶和提示
2.1.1 接口函数
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
}
2.2 方法一
方法一的想法继承的是之前的第三个问题的想法,本质上来说,方法难想,但是代码简单
2.2.1 具体步骤
由于之前给出的公式
L = N ∗ C − X L=N*C-X L=N∗C−X {N*C-X}
所以由推论可以证明,假如我把相遇点fast指针位置叫做meet,还有一个头指针head,两个指针一个从head走L
,一个从meet走会走N*C-X
,他们会在入口点相遇,正好以此求出入口点的位置
2.2.2 整体实现
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* slow=head,*fast=head;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
//相遇
struct ListNode*meet=fast;
//通过推论证明,一个指针
while(meet!=head)
{
meet=meet->next;
head=head->next;
}
return meet;
}
}
return NULL;
}
2. 3方法二
相对于方法一来说方法二想法简单但是代码复杂
2.3.1 想法和思路
先快慢指针相遇,然后我们把相遇的点置空,创建一个newhead
节点,然后和head一起走的话就转变成之前做过的相交问题了,以此找出交点所在就是我们要求的
这里就不在这里写这个方法了
小结:
环形链表的这道题主要还是比较考验数学思想的一道题目,有这样一个想法很重要
如果老铁们有收获的话,希望给个一键三连哦,谢谢