题目描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
思路:找一快一慢两个指针,慢指针一次走一步,快指针一次走两步,然后如果有环会相遇,否则就会变为NULL。然后就有两种想法,一种是找到环的长度,然后找两个指针,一个先走环的长度,另一个从起点出发,相遇的地方就是环的入口。还有两一种更优秀的思路,一快一慢两个指针,假设环外链表长度为a,环的长度为b,相遇点拒环的入口长度为c,那么相遇时满足a+b+c=2*(a+c),然后能得到c=b-a,所以让快指针回到起点,然后每次走一步就能和慢指针在环的入口相遇。
代码:第一份代码是我自己的,第一种思路,然后贴了剑指offer的第一种思路的方法,第三份代码是第二种思路,很简洁。
/*
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,*p2=pHead;
while(p1->next!=NULL&&p2->next!=NULL){
p1=p1->next;
p2=p2->next;
if(p2->next!=NULL)
p2=p2->next;
if(p1==p2){
int len = LoopLength(p1);
ListNode* e = FindEntry(pHead,len);
return e;
}
}
return NULL;
}
int LoopLength(ListNode* p){
int cou=1;
ListNode* tem = p->next;
while(p!=tem){
cou++;
tem=tem->next;
}
return cou;
}
ListNode* FindEntry(ListNode* p,int len){
ListNode* entry = p;
for(int i=0;i<len;i++){
entry=entry->next;
}
while(entry!=p){
entry=entry->next;
p=p->next;
}
return entry;
}
};
链接:https://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4
来源:牛客网
|
链接:https://www.nowcoder.com/questionTerminal/253d2c59ec3e4bc68da16833f79a38e4
来源:牛客网
|