剑指offer_编程题_链表中环的入口结点
移动开发
2020-04-27 12:38:57
阅读次数: 0
- 遍历链表并存储,若发现一节点已经遍历过,则该节点为入口结点
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if (pHead==NULL)
return NULL;
ListNode* temp = pHead;
std::map<ListNode*, int> m;
while(temp->next!=NULL)
{
if (m.count(temp)>0)
return temp;
else
m[temp] = 1;
temp = temp->next;
}
return NULL;
}
};
- 遍历链表,并将已遍历节点的next指向一个自定义的节点
若即将遍历的节点指向自定义的节点,则为入口结点/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if (pHead==NULL)
return NULL;
ListNode* mybase = new ListNode(0);
ListNode* temp;
while(pHead->next!=NULL&&pHead->next!=mybase)
{
temp = pHead->next;
pHead->next = mybase;
pHead = temp;
}
if (pHead->next==NULL)
return NULL;
else
return pHead;
}
};
- 通过两个指针分别以1的速度、2的速度移动,若存在环,则两指针必定相遇
假设存在环,环长为n,即节点数量为n,并设入口点为第一个节点
当1走到环的第一个节点时,2可能出现在环上的任意一点x(1<=x<=n)
①此时,如果2降低速度为1,那么2永远处在1的前方(x-1)个位置
如果2停下,1需要走(x-1)与2相遇
也就是说,1如果从开始处出发,2在环的第一个节点处等待(x-1)个时间后以与1相同的速度出发,那么两指针会相遇
②当1走到环的第一个节点时,如果2仍然以2的速度前进,两者速度2比1快1,2将会追上1
环长为n,2在1的前方(x-1)个位置,2如果要追上1,需要[n-(x-1)]个时间
即1和2的相遇点为(1+[n-(x-1)]),相遇点到环的第一个节点的距离为(n-[(1+[n-(x-1)])-1])=(x-1)
由①1如果从开始处出发,2在环的第一个节点处等待(x-1)个时间后以与1相同的速度出发,那么两指针会在入口处相遇
所以有1从开始处出发,2从相遇点出发,以同样的速度1,两个指针在入口会相遇
参考/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead)
{
if (pHead==NULL)
return NULL;
ListNode* p1=pHead;
ListNode* p2=pHead;
while(p2!=NULL&&p2->next!=NULL)
{
p1 = p1->next;
p2 = p2->next->next;
if (p1==p2)
{
p1 = pHead;
while(p1!=p2)
{
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
}
return NULL;
}
};
发布了80 篇原创文章 ·
获赞 18 ·
访问量 1万+
转载自blog.csdn.net/C_abua/article/details/105749408