注:基于jeanphorn‘s csdn文章进行修改而成。
1. 问题描述
给定两个单链表,查找这两个单链表的交叉节点。例如:链表listA为:a1→a2→c1→c2→c3,链表listB为:b1→b2→b3→c1→c2→c3。那么这两个的第一个交叉节点为c1。
2. 方法与思路
首先,观察一下交叉节点的特点。如果两个链表有交叉节点的话,那么这个交叉节点之后的其他节点都是相同的,也就是说两个链表的结构应该是Y字型的。
也就是说,c1之后的节点都是交叉节点。下面的问题就是如何确定c1这个节点,我们可以设两个指针分别遍历两个链表,然后对比节点的值,但是两个链表可能是不等长的,我们可以先让长度较大的链表指针先走|len(listA)−len(listB)|步,然后在同步进行。
时间复杂度O(n+m+n)(注:n为较长的链表的长度,m为较短的链表的长度),空间复杂度O(1)。
c++代码如下:
1 //求出链表长度 2 int getListLength(ListNode *head) 3 { 4 int len = 0; 5 ListNode *tmp = head; 6 while(tmp){ 7 tmp = tmp->next; 8 len++; 9 } 10 return len; 11 } 12 //判断交叉节点 13 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 14 ListNode *a = headA, *b = headB; 15 16 int ab = getListLength(a)-getListLength(b); 17 18 if(ab > 0) 19 { 20 while(ab) a = a->next, ab--; 21 } 22 else if(ab < 0) 23 { 24 while(ab) b = b->next, ab++; 25 } 26 27 while(a && b) 28 { 29 if(a->val == b->val) return a; 30 31 a = a->next; 32 b = b->next; 33 } 34 35 return NULL; 36 }