Day81 | 灵神 | 快慢指针 链表的中间结点 环形链表

876.链表的中间结点

876. 链表的中间结点 - 力扣(LeetCode)

思路:

设置两个指针,一个快指针r一个慢指针l

初始都是头结点

我们要求的是中间节点

所以快指针走两步,慢指针走一步,那么就可以在快指针走到末尾时慢指针就指向中间结点

链表长度为奇数

image-20250403084802147

链表长度为偶数

image-20250403084833124

所以就是快指针为空或者下一个为空,那就停止循环

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *l=head;
ListNode *r=head;
while(r!=nullptr&&r->next!=nullptr)
{
l=l->next;
r=r->next->next;
}
return l;
}
};

141.环形链表

141. 环形链表 - 力扣(LeetCode)

思路:

有了上一题的基础我们很容易想到设置快慢指针

只要有环,那快指针总有追上慢指针的一天

以下是灵神的题解(比笔者说的好理解,就贴过来了

想象兔子和乌龟在同一跑道上,一个速度快、另一个速度慢。如果跑道有环,兔子必然在一段时间后追上乌龟。对于链表来说,如果在链表中引入两个以不同速度(一个比另一个快一倍)前进的指针,在链表存在环的情况下,这两个指针必定会相遇。

兔子会不会「跳过」乌龟,从来不会和乌龟相遇呢?

答:这是不可能的。如果有环的话,那么兔子和乌龟都会进入环中。这时用「相对速度」思考,乌龟不动,兔子相对乌龟每次只走一步,这样就可以看出兔子一定会和乌龟相遇了。

完整代码:

⚠注意:代码比较两个节点的时候,比较的是内存地址是否一致,即节点是否相同,并没有比较节点的 val。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode* l=head;
ListNode* r=head;
while(r!=nullptr&&r->next!=nullptr)
{
r=r->next->next;
l=l->next;
if(r==l)
return true;
}
return false;
}
};