题目一 环形链路
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle
还是先上图
我们先来看有环的情况
这个时候实际上fast和slow会在里面陷入死循环
我们把这个图再抽象下
实际上就是一个这样子的图形
大家有没有表示眼熟?
这不就是我们的操场吗
那么我们把问题变一下
两个人跑步 一个跑的比较快 一个跑的比较慢
如果在一个直线的操场上它们会相遇嘛?
显然不会
但是如果在一个环形的操场上呢?
那必然会啊
那么我们接着来看
我们证明这两个问题后,环的问题就很简单了,直接上手写代码
* struct ListNode {
*int val;
*struct ListNode* next;
*
};
*/
bool hasCycle(struct ListNode* head) {
struct ListNode* slow, * fast;
slow = fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
return true;
}
}
return false;
}
题目二 环形链表二
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/linked-list-cycle-ii
这一题跟上一题一样但又不一样
我们又要证明一个结论
我们按照这个结论写代码会非常简单
* struct ListNode {
*int val;
*struct ListNode* next;
*
};
*/
struct ListNode* detectCycle(struct ListNode* head) {
struct ListNode* slow, * fast;
slow = fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
struct ListNode* meet = slow;
struct ListNode* start = head;
while (meet != start)
{
start = start->next;
meet = meet->next;
}
return meet;
}
}
return NULL;
}
还有一种不用结论的方法,找入口问题转换成找链表交点问题
* struct ListNode {
*int val;
*struct ListNode* next;
*
};
*/
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {
struct ListNode* tailA = headA, * tailB = headB;
int lenA = 1;
int lenB = 1;
//计算链表A的长度
while (tailA->next)
{
tailA = tailA->next;
++lenA;
}
while (tailB->next)//B的长度
{
tailB = tailB->next;
++lenB;
}
int gap = abs(lenA - lenB);//长度差的绝对值
struct ListNode* longlist = headA, * shortlist = headB;
if (lenA < lenB)//判断谁长谁短
{
longlist = headB;
shortlist = headA;
}
//长的先走差距步
while (gap--)
{
longlist = longlist->next;
}
//同时走
while (longlist != shortlist)
{
longlist = longlist->next;
shortlist = shortlist->next;
}
return longlist;
}
struct ListNode* detectCycle(struct ListNode* head) {
struct ListNode* slow, * fast;
slow = fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
{
struct ListNode* meet = slow;
struct ListNode* lit1 = head;
struct ListNode* lit2 = meet->next;
meet->next = NULL;
return getIntersectionNode(lit1, lit2);
}
}
return NULL;
}
以上便是本文所有内容了,如有错误请各位大佬不吝赐教,感谢留言