Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
null
.
算法一:
设立2个指针,各指向一个链表头部。
同时向前,直到找到相同节点。
当指针遍历到链表尾部时,该指针重新指向另一链表的头部。
算法能工作的原理为:
设两者有交点。
A 链表的节点数为 m + c
B 链表的节点数为 n + c
其中, c为 相交节点数。 即共享的节点数。
m, n则为链表各自不节享节数。
则有 m + c + n == n + c + m
此式意义为:
设p1 初始指向A链表,p2初始指向B链表。
当p1 经过遍历完A链表(m+c个节点),并且遍历B链表n个节点后,p1来到交点处。
而此时p2 也刚好到了交点处。即遍历完B链表(n+c个节点), 且遍历A链表m个节点。
故能找到交点。
下面代码,当不存在交点时,如何退出循环的呢。
p1在遍历完A链表,并遍历完B链表后,此时,它到B链表末尾;
而此时p2,遍历完B链表,也一定处在A链表末尾; 因为两个指针都完成把两个链表同时遍历一次。
即此时,p1和p2指针同时为空。
所以在两个链表不存在交点时,遍历的结点数为两个链表之和。
另外,如果两个链表长度相等情况下,将会提前结束。即只需遍历完一个链表长度。
下面这行代码,是处理交点不存在时的关键:
if (p1 == p2) return p1;
在leetcode 上实际执行时间为52ms。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { if (!headA || !headB) return NULL; ListNode *p1 = headA; ListNode *p2 = headB; while (p1 != p2) { p1 = p1->next; p2 = p2->next; if (p1 == p2) return p1; if (!p1) p1 = headB; if (!p2) p2 = headA; } return p1; } };算法来源:
算法二
此算法为较常见的思路:
1. 先统计两者链表的长度。
2. 设立2指针,分表指向两个链表。 并使较长的链表,先行步进指针。步进的步数,为长度差值。
3. 然后作比较,并同时步进2个针指针。
此算法在leetcode上实际执行时间为56ms。
对比起来,此算法的时间复杂度,并不差于算法一。
class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { if (!headA || !headB) return NULL; int sizeA = 0; ListNode *p = headA; while (p) { p = p->next; ++sizeA; } int sizeB = 0; p = headB; while (p) { p = p->next; ++sizeB; } while (sizeA > sizeB) { headA = headA->next; --sizeA; } while (sizeB > sizeA) { headB = headB->next; --sizeB; } while (headA && headA != headB) { headA = headA->next; headB = headB->next; } return headA; } };
Intersection of Two Linked Lists -- leetcode
原文地址:http://blog.csdn.net/elton_xiao/article/details/46572097