目录
环形问题的思考
❓Q1
❓Q2
Q2
❓Q3
❓Q4
8.环形链表
9.环形链表Ⅱ
今天接着链表的经典问题环形问题。大家一定要自己动手多写写。
假设现有一个链表是带环的,请你做出如下思考和证明! (环形链表如下)
slow一次走1步,fast一次走2步,他们一定会相遇吗?(slow在走满一圈之前)
假设链表带环,两个指针最后都会进入环,快指针先进环,慢指针后进环。当慢指针刚进环时,可能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度。此时,两个指针每移动一次,之间距离缩小一步,不会出现每次刚好是套圈的情况。
slow一次走1步,fast一次走3步,他们一定会相遇吗?
在上面的基础上,请问N是奇数,C是偶数,C-1是奇数这个条件是否成立。请证明!
slow一次走n步,fast一次走m步,他们一定会相遇吗?(m>n>1)
请证明:
让一个指针slow从链表起始位置开始遍历链表,同时让一个指针fast从判环时相遇点的位置开始绕环运行,注意slow每次走1步,fast每次走1步,最终肯定会在入口点的位置相遇。
给你一个链表的头节点
head
,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递 。仅仅是为了标识链表的实际情况。如果链表中存在环 ,则返回
true
。 否则,返回false
。
输入:head = [3,2,0,-4], pos = 1 输出:true 解释:链表中有一个环,其尾部连接到第二个节点。
【快慢双指针】
思路:快慢指针,即慢指针一次走一步,快指针一次走两步,两个指针从链表其实位置开始运行,
如果链表带环则一定会在环中相遇,否则快指针率先走到链表的末尾。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head)
{
struct ListNode *faster=head;
struct ListNode *slow=head;
//一起走faster走2步 slow走1步--保持相对速度
while(faster && slow && faster->next)
{
faster=faster->next->next;
slow=slow->next;
if(slow == faster)
{
return true;
}
}
return false;
}
//另外写法
bool hasCycle(struct ListNode *head)
{
struct ListNode *faster=head;
struct ListNode *slow=NULL;
if(head == NULL)
{
return false;
}
while(faster != slow)
{
if(slow == NULL)
{
slow=head;
}
if(faster == NULL || faster->next == NULL)
{
return false;
}
faster=faster->next->next;
slow=slow->next;
}
return true;
}
给定一个链表的头节点
head
,返回链表开始入环的第一个节点。 如果链表无环,则返回null
。如果链表中有某个节点,可以通过连续跟踪
next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果pos
是-1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表。
输入:head = [3,2,0,-4], pos = 1 输出:返回索引为 1 的链表节点 解释:链表中有一个环,其尾部连接到第二个节点。
【快慢指针】
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head)
{
struct ListNode *slow=head;
struct ListNode *fast=head;
struct ListNode *meet=NULL;
while(fast && fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast == slow)
{
slow=head;
while(fast != slow)
{
slow=slow->next;
fast=fast->next;
}
return fast;
}
}
return NULL;
}
【链表的相交】
感谢各位!下篇我们开始双向链表的学习。一起加油小伙伴们!
【链表练习题】链表知识点题库 - 力扣(LeetCode)
牛客网在线编程_算法篇_面试必刷TOP101 (nowcoder.com)
代码---------→【唐棣棣 (TSQXG) - Gitee.com】
联系---------→【邮箱:[email protected]】