前言
好好刷题!!!
一、题目描述
二、题解描述
有两个方法;
- 先判断是否带环,不带环简单,直接返回空;使用快慢指针判断交点位置返回值带回来,让返回节点的下一个节点当成第二条链表的头,第一条链表头不变,然后返回的节点就是两链表的最后一个相同交点了嘛;先让返回的节点的next指向空(一定要最先得到循环链表返回节点的下一个节点,也就是第二条链表的头节点才可以让节点的next位空,不然第二条链表头节点会丢失);最后看链表是否要恢复,也就是返回节点的next是否要恢复指向第二条链表的头,看是否报错,不报错就不用恢复;
现在得到了两条链表,然后两条链表的最开始的一个相交节点不就是人口节点吗?这样就找到了;而两条链表相交的题目我以前的链表博客特地写过题解,不知道的可以看一下;- 先判断带不带环,不带就返回空;这个方法是公式法;
2*(L+X)=L+X+NC;
L+X=NC;
L=N*C-X;
L=(N-1)*C+C-X;
L是头到人口的长度,C是环周长,X是人口到快慢指针相交的节点的长度,N是圈数,也就是绕了多少周环;
所以从头到人口节点的长度L等于(N-1)*C圈长度加环的长度减人口到快慢指针相交的节点的长度;所以一个指针从头节点开始走,另一个指针从快慢指针交点开始走,都一次走一步,相交的时候的节点就是人口节点;
三. 代码实现
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param pHead ListNode类
* @return ListNode类
*/
struct ListNode* IsMeet(struct ListNode* pHead){
struct ListNode* fast=pHead,*slow=pHead;
while(fast&&fast->next){
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
return fast;
}
return NULL;
}
struct ListNode* EntryNodeOfLoop(struct ListNode* pHead ) {
// write code here
if(IsMeet(pHead)==NULL){
return NULL;
}
else{
struct ListNode* cur=IsMeet(pHead);
struct ListNode* prev=pHead;
while(prev!=cur){
cur=cur->next;
prev=prev->next;
}
return prev;
}
}
总结
一定要多刷题!!!