Algorithm to Find the 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:

two-linked-list-intersection-1 Algorithm to Find the Intersection of Two Linked Lists algorithms c / c++ data structure

Intersection of Two Linked Lists

begin to intersect at node c1.

Example 1:

two-linked-list-intersection-2 Algorithm to Find the Intersection of Two Linked Lists algorithms c / c++ data structure

Intersection of Two Linked Lists

Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
Output: Reference of the node with value = 8
Input Explanation: The intersected node’s value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,0,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B.

Example 2:

two-linked-list-intersection-3 Algorithm to Find the Intersection of Two Linked Lists algorithms c / c++ data structure

Intersection of Two Linked Lists

Input: intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
Output: Reference of the node with value = 2
Input Explanation: The intersected node’s value is 2 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [0,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B.

Example 3:

two-linked-list-intersection-4 Algorithm to Find the Intersection of Two Linked Lists algorithms c / c++ data structure

Intersection of Two Linked Lists

Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output: null
Input Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values.
Explanation: The two lists do not intersect, so return null.

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.

How to Check if Two Linked List Intersect?

Like many other problems, we can use bruteforce algorithm: for each node in Linked list A, we need to check if it is in Linked List B. This will take O(MN) time where M and N are the lengths for the two linked lists repsectively. The space complexity is O(1) constant.

Could we do better? we can use a hash set to remember a linked list. We can pick either A or B linked list. The complexity is O(M + N) and the space complexity is O(M) or O(N) depending on choice.

The following C++ algorithm finds the intersection node of two singly-linked list.

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
/**
 * 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) {
        unordered_set<ListNode*> data;
        while (headA != nullptr) {
            data.insert(headA);
            headA = headA->next;
        }
        while (headB != nullptr) {
            if (data.count(headB)) {
                return headB;
            }
            headB = headB->next;
        }
        return nullptr;
    }
};
/**
 * 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) {
        unordered_set<ListNode*> data;
        while (headA != nullptr) {
            data.insert(headA);
            headA = headA->next;
        }
        while (headB != nullptr) {
            if (data.count(headB)) {
                return headB;
            }
            headB = headB->next;
        }
        return nullptr;
    }
};

Finding the Intersection Node of Two LinkList using Two Pointers Algorithms

We can use the two pointers algorithms to find the intersection point. This works because the given two linked list does not have cycle. We can move one step at a time, and when it reaches the end, we then move to the begining of the same ListList or the other LinkList.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 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) {
        auto p1 = headA;
        auto p2 = headB;
        while (p1 != p2) {
            p1 = p1 ? p1->next : headB;
            p2 = p2 ? p2->next : headA;
        }
        return p1;
    }
};
/**
 * 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) {
        auto p1 = headA;
        auto p2 = headB;
        while (p1 != p2) {
            p1 = p1 ? p1->next : headB;
            p2 = p2 ? p2->next : headA;
        }
        return p1;
    }
};

Alternatively, we can jump to the head of the same LinkList:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 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) {
        auto p1 = headA;
        auto p2 = headB;
        while (p1 != p2) {
            p1 = p1 ? p1->next : headA;
            p2 = p2 ? p2->next : headB;
        }
        return p1;
    }
};
/**
 * 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) {
        auto p1 = headA;
        auto p2 = headB;
        while (p1 != p2) {
            p1 = p1 ? p1->next : headA;
            p2 = p2 ? p2->next : headB;
        }
        return p1;
    }
};

This approach works because eventually two pointers will collide – the time complexity is O(M+N). and the space requirement is O(1) constant.

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
931 words
Last Post: The Custom Sort String Algorithm with Count and Write
Next Post: How to Run a Specified Set of Javascript (NodeJS) Unit Tests using Mocha?

The Permanent URL is: Algorithm to Find the Intersection of Two Linked Lists

Leave a Reply