struct ListNode
{
int val;
struct ListNode* next;
};
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB);
方法一---长链表先走长度差,两者同步遍历到相交结点
两个单链表,判断是否相交,若相交返回相交结点,不相交返回NULL。
如果相交,由于结点的next指针只能指向一个结点,那么两个链表在相交后的结点就都是相同结点
那么如果两个链表相交,他们的尾结点一定相同,因此我们通过遍历得到的尾结点是否相同来判断两个链表是否相交。对于相交结点的返回,我们观察可以知道,两个链表的长度差,如果我们让长链表走长度差的步数,两个链表再以相同速度一同遍历,那么当遍历到结点相同时,就得到了相交结点,这就是本题的大致思路。
首先,如果两个链表其中有一个为NULL,那么就不存在相交结点,然后我们分别遍历两个链表拿到尾结点,通过尾结点是否相同来判断两者是否相交。相交则计算长度差,然后两次移动,第一次长链表移动长度差,第二次两个链表一起移动直到结点相同停止。
if((headA==NULL) || (headB==NULL))
return NULL;
struct ListNode* curA = headA;
struct ListNode* curB = headB;
int A = 1;
int B = 1;
遍历得到尾结点顺便计算两个链表的长度:
while(curA->next)
{
curA= curA->next;
A++;
}
while(curB->next)
{
curB = curB->next;
B++;
}
判断尾结点是否相同,不相同返回NULL:
if(curA != curB)
return NULL;
相同我们创建一个变量n接收一下长度差的绝对值,使用假设判断法创建一个Longlist和Shortlist,先把headA赋给Longlist,headB赋给Shortlist,通过if判断,如果A<B,将headB赋给Longlist,headA赋给Shortlist:
int n =abs(A-B);
struct ListNode* Longlist = headA , *Shortlist = headB;
if(A<B)
{
Longlist = headB;
Shortlist = headA;
}
那么我们先让长链表Longlist走n步,然后让Longlist和Shortlist同步走直到两者相同即相交结点:
while(n--)
{
Longlist=Longlist->next;
}
while(Longlist!=Shortlist)
{
Longlist=Longlist->next;
Shortlist=Shortlist->next;
}
return Longlist;//Shortlist
整体代码如下:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if((headA==NULL) || (headB==NULL))
return NULL;
struct ListNode* curA = headA;
struct ListNode* curB = headB;
int A = 0;
int B = 0;
while(curA->next)
{
curA= curA->next;
A++;
}
while(curB->next)
{
curB = curB->next;
B++;
}
if(curA != curB)
return NULL;
int n =abs(A-B);
struct ListNode* Longlist = headA , *Shortlist = headB;
if(A<B)
{
Longlist = headB;
Shortlist = headA;
}
while(n--)
{
Longlist=Longlist->next;
}
while(Longlist!=Shortlist)
{
Longlist=Longlist->next;
Shortlist=Shortlist->next;
}
return Longlist;//Shortlist
}
方法二---暴力遍历,嵌套循环
我们遍历链表A,在每次遍历的时候将结点与每个链表B的结点进行对比,相同则为相交结点,返回;不同则继续遍历。如果出了嵌套循环,那么就返回NULL。不做过多阐述。
//方法二:暴力遍历
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
struct ListNode* cur1 = headA;
while (cur1)
{
struct ListNode* cur2 = headB;
while (cur2)
{
if (cur1 == cur2)
return cur2;
cur2 = cur2->next;
}
cur1 = cur1->next;
}
return NULL;
}