判断链表是否与环
思路:建立两个指针,一个快指针,一个慢指针.快指针走两步,慢指针走一步,如果有环,则在环内会产生追击问题.如果快指针和慢指针相遇,则有环.
为什么要选择慢指针走一步,快指针走两步?原因如下:
慢指针走一步,快指针走三步不可以的原因:
代码如下所示:
#include<stdbool.h>
struct ListNode
{
int val;
struct ListNode* next;
};
bool hasCycle(struct ListNode* head)
{
struct ListNode* slow = head;
struct ListNode* fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
return true;
}
}
return false;
}
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
思路:先找到相遇点,一个从相遇点走,一个从头节点走,相等则返回入环的头节点
代码如下:
#include<stdio.h>
#include<stdbool.h>
struct ListNode
{
int val;
struct ListNode* next;
};
struct ListNode* detectCycle(struct ListNode* head)
{
struct ListNode* slow = head;
struct ListNode* fast = head;
while (fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
{
struct ListNode* meet = slow;
while(meet!=head)
{
meet = meet->next;
head = head->next;
}
return meet;
}
}
return NULL;
}
随机链表的复制
给你一个长度为 n
的链表,每个节点包含一个额外增加的随机指针 random
,该指针可以指向链表中的任何节点或空节点。
#include<stdio.h>
#include<stdbool.h>
struct Node {
int val;
struct Node* next;
struct Node* random;
};
struct Node* copyRandomList(struct Node* head)
{
struct Node* cur = head;
while (cur)
{
struct Node* copy = (struct Node*)malloc(sizeof(struct Node));
copy->val = cur->val;
copy->next = cur->next;
cur->next = copy;
cur = copy->next;
}
cur = head;
while (cur)
{
struct Node* copy = cur->next;
if (cur->random == NULL)
{
copy->random = NULL;
}
else
{
copy->random = cur->random->next;
}
cur = copy->next;
}
struct Node* copyhead = NULL;
struct Node* copytail = NULL;
cur = head;
while (cur)
{
struct Node* copy = cur->next;
struct Node* next = copy->next;
if (copytail == NULL)
{
copyhead = copytail = copy;
}
else
{
copytail->next = copy;
copytail = copytail->next;
}
//cur->next = next;
cur = next;
}
return copyhead;
}