某教练同时带教两位学员,分别以链表 l1、l2 记录了两套核心肌群训练计划,节点值为训练项目编号。两套计划仅有前半部分热身项目不同,后续正式训练项目相同。请设计一个程序找出并返回第一个正式训练项目编号。如果两个链表不存在相交节点,返回 null 。

此题是寻找链表公共结点,设公共部分长c,单独的部分分别为a,b
首先想到的是先同时遍历两个链表,当短的一方遍历结束时(共a+c),另一方也遍历了(a+c),另一方还需要遍历(b-a),而从头遍历的话A需要遍历a,B需要遍历b
再次从头遍历B,当b-a遍历结束时,还需遍历(a)即可到达公共结点,此距离与从头遍历A的距离相等,
所以此时同时开始遍历A,两节点在遍历过程中一定会相交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { if (headA == NULL || headB == NULL) return NULL; ListNode *i = headA, *j = headB; while (i != NULL && j != NULL) { i = i->next; j = j->next; } if (i == NULL) { i = headB; } if (j == NULL) { j = headA; } while (i != NULL && j != NULL) { i = i->next; j = j->next; } if (i == NULL) { i = headB; } if (j == NULL) { j = headA; } while (i != NULL && j != NULL && i != j) { i = i->next; j = j->next; } return i; } };
|
总的来说两节点遍历的距离都是a+b+c,速度一样,两指针一定同时到达终点
我们可以把遍历过程分为三段,每段路程分别为a,b,c,当 i 跑完a+c时我们将他放到b继续跑
对于 j 同理,二者最后一定同时到达交点(无交点时可以假设NULL为交点)
1 2 3 4 5 6 7 8 9 10 11
| class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode *i = headA, *j = headB; while (i != j) { i = i == NULL ? headB : i->next; j = j == NULL ? headA : j->next; } return i; } };
|