编写一个程序,找到两个单链表相交的起始节点。
例如,下面的两个链表:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
在节点 c1 开始相交。
注意:
- 如果两个链表没有交点,返回
null
. - 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
- 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
致谢:
特别感谢 @stellari 添加此问题并创建所有测试用例。
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) { if(headA == NULL || headB == NULL) return NULL; struct ListNode *pa = headA; struct ListNode *pb = headB; if(pa == pb) return pa; int lenA = 1; int lenB = 1; while(pa->next || pb->next) { if(pa->next) { pa = pa->next; lenA++; } if(pb->next) { pb = pb->next; lenB++; } } /*假如相交,pa,pb都处于链尾。则有pa = pb*/ if(pa != pb) return NULL; /*找到相交的那一节点, 利用相交的那段必是地址是一致的,且长度是相等的*/ int i; int len; if(lenA >= lenB) { len = lenA-lenB; pa = headA; pb = headB; for(i=0; i < len; i++) { pa = pa->next; } } else { len = lenB-lenA; pa = headA; pb = headB; for(i=0; i < len; i++) { pb = pb->next; } } while(pa != pb) { pa = pa->next; pb = pb->next; } return pa; }