LeetCode: Intersection of Two Linked Lists 解题报告

Intersection of Two Linked Lists

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:

  • If the two linked lists have no intersection at all, return null.
  • The linked lists must retain their original structure after the function returns.
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.

Credits:
Special thanks to @stellari for adding this problem and creating all test cases.

 

SOLUTION 1:

1.各自遍历链表,分别取得长度;

2.较长一条链表移动abs(lengthA-lengthB)个节点;

3.同时移动指针,判断是否相等。

 

(O(n+m) running time, O(1) memory)

 

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
12 
13         //my solution
14         if(headA == NULL && headB == NULL) {
15             return NULL;
16         }
17         if(headA && headB) {
18             ListNode *it;
19             it = headA;
20             int lengthA = 0;
21             while(it) {
22                 lengthA++;
23                 it = it->next;
24             }
25             it = headB;
26             int lengthB = 0;
27             while(it) {
28                 lengthB++;
29                 it = it->next;
30             }
31             it = NULL;
32             ListNode *itA = headA;
33             ListNode *itB = headB;
34     
35             if(lengthA > lengthB) {
36                 for(int i = 0; i < lengthA-lengthB; i++) {
37                     itA = itA->next;
38                 }
39             } else {
40                 for(int i = 0; i < lengthB-lengthA; i++) {
41                     itB = itB->next;
42                 }
43             }
44             while(itA != itB) {
45                 itA = itA->next;
46                 itB = itB->next;
47             }
48             return itA;
49         } else {
50             return NULL;
51         }
52 }
View Code

 

 SOLUTION 2:

LeetCode提供的解法:

  • Hashset solution (O(n+m) running time, O(n) or O(m) memory):

    Traverse list A and store the address / reference to each node in a hash set. Then check every node bi in list B: if bi appears in the hash set, then bi is the intersection node.

  这样做比较占用空间。没有去写这个解法的代码;

SOLUTION 3:

LeetCode的解法:

Two pointer solution (O(n+m) running time, O(1) memory):

  • Maintain two pointers pA and pB initialized at the head of A and B, respectively. Then let them both traverse through the lists, one node at a time.
  • When pA reaches the end of a list, then redirect it to the head of B (yes, B, that's right.); similarly when pB reaches the end of a list, redirect it the head of A.
  • If at any point pA meets pB, then pA/pB is the intersection node.
  • To see why the above trick would work, consider the following two lists: A = {1,3,5,7,9,11} and B = {2,4,9,11}, which are intersected at node '9'. Since B.length (=4) < A.length (=6), pB would reach the end of the merged list first, because pB traverses exactly 2 nodes less than pA does. By redirecting pB to head A, and pA to head B, we now ask pB to travel exactly 2 more nodes than pA would. So in the second iteration, they are guaranteed to reach the intersection node at the same time.
  • If two lists have intersection, then their last nodes must be the same one. So when pA/pB reaches the end of a list, record the last element of A/B respectively. If the two last elements are not the same one, then the two lists have no intersections.

其实本质和solution 1 差不多,都是把两个链表的长度差消去。但是这样写感觉很屌。

自己写的代码:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
12 
13         // solution 3
14         if(headA == NULL && headB == NULL) {
15             return NULL;
16         }
17         if(headA && headB){
18             ListNode *pA = headA;
19             ListNode *pB = headB;
20             while(pA != pB){
21                 if(pA == NULL && pB == NULL){
22                     return NULL;
23                 }
24                 if(pA == NULL){
25                     pA = headB;
26                 }
27                 if(pB == NULL){
28                     pB = headA;
29                 }
30 //if the intersection is the last node
31                 if(pA == pB){
32                     return pA;
33                 }
34                 pA = pA->next;
35                 pB = pB->next;
36             }
37             return pA;
38         }
39         return NULL;
40     }
41 };
View Code

 

posted @ 2015-02-27 17:14  伪cnblog_com  阅读(133)  评论(0编辑  收藏  举报