给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
图示两个链表在节点 c1 开始相交:

题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
首先我们得明白,单链表只有一个next指针,如果两个单链表相交,那从相交结点开始,两链表完全相同,所以相交链表一定是Y字型的,不可能出现X型.,并且如果两链表最后一个结点不相同,则两链表一定不相交.
思路1:(暴力求解):
依次取第一个链表的一个结点与第二个链表的全部结点相比较(这里要注意比较的是结点的地址),若找到地址相同的结点,那么该结点就是相交结点,若遍历完第一个链表还没有找到,则表示两链表没有相交,其时间复杂度为O(n^2)
思路二:

如果相交链表是上如所示形状,那便可以取第一个链表的第一个结点与第二个链表的第一个结点比较,若不相同,继续比较两链表的第二个几点,直到找到相交结点.这样就可以把时间复杂度控制到O(n),这种方法虽然有效,但是碰到下图所示情况就没办法用了:

思考一下,如果两个链表相交的话,假设第一个链表在相交结点前有n个结点,第二个链表在相交结点前有m个结点,(假设n>m),那么第一个链表的前n-m个结点肯定不是相交结点.
所以就可以分别遍历两个链表并求出其长度,让较长的链表先走两链表长度的差值步,使两链表相交结点前的结点数相同,这样就可以用上面讲的思路了.
这里有两个小细节:
参考代码:
-
- struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
- struct ListNode *curA=headA;
- struct ListNode *curB=headB;
- int lenA=0;
- int lenB=0;
- while(curA->next)
- {
- lenA++;
- curA=curA->next;
- }
- while(curB->next)
- {
- lenB++;
- curB=curB->next;
- }
-
- if(curA!=curB)
- return NULL;
- //假设长的链表为A
- struct ListNode *longlist=headA;
- struct ListNode *shortlist=headB;
- if(lenA<lenB)
- {
- longlist=headB;
- shortlist=headA;
- }
- int n=abs(lenA-lenB);
- //先让长链表先走
- while(n--)
- {
- longlist=longlist->next;
- }
- //两个链表同时走找相交结点
- while(longlist!=shortlist)
- {
- longlist=longlist->next;
- shortlist=shortlist->next;
- }
- return longlist;
- //return shortlist;
- }
