[关闭]
@ChristopherWu 2016-06-16T13:31:32.000000Z 字数 2884 阅读 1190

Intersection of Two Linked

leetcode


160. Intersection of Two Linked Lists

Question

Write a program to find the node at which the intersection of two singly linked lists begins.

For example, the following two linked lists:

  1. A: a1 a2
  2. c1 c2 c3
  3. B: b1 b2 b3

begin to intersect at node c1.

Notes:

Solution

Approach #1 (count the difference of two list's length) [Accepted]

Algorithm

Let's say list A and list B, at first, we caculate their length.
If A is longer, A traversed the difference steps to arrive at the relative start position of B and vice versa.
Then they traversed to the end together, eventually cur1 and cur2 will meet at the intersection point or nullptr.

  1. class Solution {
  2. public:
  3. ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
  4. int list_A_len = 0, list_B_len = 0, diff = 0;
  5. ListNode *tmp_A = headA;
  6. ListNode *tmp_B = headB;
  7. while(tmp_A) {
  8. tmp_A = tmp_A->next;
  9. ++list_A_len;
  10. }
  11. while(tmp_B) {
  12. tmp_B = tmp_B->next;
  13. ++list_B_len;
  14. }
  15. diff = list_A_len - list_B_len;
  16. if(diff > 0) {
  17. while(diff--) {
  18. headA = headA->next;
  19. }
  20. }else {
  21. while(diff++) {
  22. headB = headB->next;
  23. }
  24. }
  25. while(headA && headB) {
  26. if(headA == headB) {
  27. return headA;
  28. }else {
  29. headA = headA->next;
  30. headB = headB->next;
  31. }
  32. }
  33. return nullptr;
  34. }
  35. };

Complexity Analysis

Suppose m is greater than n, than time complexity is O(m+n + m-n + n), in other words, O(2m+n).


Approach #2 (make a Linked List Cycle) [Accepted]

Algorithm

Remember how to find the node where the Linked List Cycle begins?

We can let listA's tail ->next equal to listB's head, so that listA and listB became a Linked List Cycle, whose Cycle begin node is IntersectionNode of list A and B.
After finding the IntersectionNode, we need to recover two lists from the Linked List Cycle by tail->next = nullptr;

  1. class Solution {
  2. public:
  3. ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
  4. if(headA!=nullptr || headB!=nullptr)
  5. return nullptr;
  6. ListNode *pA = headA, *pB = headB;
  7. while(pA->next)
  8. pA = pA->next;
  9. ListNode *tail = pA;
  10. pA->next = pB;
  11. pA = headA;
  12. while(pB && pB->next) {
  13. pB = pB->next->next;
  14. pA = pA->next;
  15. if(pB == pA)
  16. break;
  17. }
  18. if(pA != pB)
  19. return nullptr;
  20. pA = headA;
  21. while(pA != pB) {
  22. pA = pA->next;
  23. pB = pB->next;
  24. }
  25. tail->next = nullptr;
  26. return pA;
  27. }
  28. };

Complexity Analysis

Suppose A's length is m while B is n, time complexity O(m+2m+c)

Approach #3 (loop back to the other list's head) [Accepted]

Algorithm

I didn't come up with this idea, thanks for dong.wang.1694.

Two pointers traversed to the end and any time they collide or reach end together without colliding then return any one of the pointers.
If one of them reaches the end earlier then reuse it by moving it to the beginning of other list.
Once both of them go through reassigning, they will be equidistant from the collision point.

  1. ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
  2. ListNode *cur1 = headA, *cur2 = headB;
  3. while(cur1 != cur2){
  4. cur1 = cur1?cur1->next:headB;
  5. cur2 = cur2?cur2->next:headA;
  6. }
  7. return cur1;
  8. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注