Union and Intersection of two Linked Lists
Last Updated : 10 Sep, 2024
Given two singly Linked Lists, create union and intersection lists that contain the union and intersection of the elements present in the given lists. Each of the two linked lists contains distinct node values.
Note: The order of elements in output lists doesn’t matter.
Example:
Input:
head1: 10 -> 15 -> 4 -> 20
head2: 8 -> 4 -> 2 -> 10
Output:
Union: 10 -> 15 -> 4 -> 20 -> 8 -> 2
Intersection: 10 -> 4
Explanation: In these two lists 4 and 10 nodes are common. The union lists contain all the unique nodes of both lists.
Input:
head1 : 1 -> 2 -> 3 -> 4
head2 : 3 -> 4 -> 8 -> 10
Output:
Union: 1 -> 2 -> 3 -> 4 -> 8 -> 10
Intersection: 3 -> 4
Explanation: In these two lists 4 and 3 nodes are common. The union lists contain all the unique nodes of both lists.
[Naive Approach] Using Two Nested Loops - O(n * m) Time and O(n + m) Space:
The idea is to traverse both linked lists and check each element's presence in the result list to avoid duplicates. For the union, we add all unique elements from both lists. For the intersection, we only add elements that are present in both lists.
- For union - We traverse both linked lists one by one, and for each element check if the element is already present in the resulting union list, If the element is not present, insert it into the union list.
- For Intersection - We traverse the first linked list, and for each element check if the element is present in the second linked list and not already in the resulting intersection list then we will insert it into the intersection list.
Below is the implementation of the above approach:
C++ // C++ program to find union and intersection of two // unsorted linked lists #include <iostream> using namespace std; class Node { public: int data; Node* next; Node(int x) { data = x; next = nullptr; } }; // Function to check if a value is present in the linked list bool isPresent(Node* head, int value) { Node* curr = head; while (curr != nullptr) { if (curr->data == value) { return true; } curr = curr->next; } return false; } // Function to find the union of two linked lists Node* findUnion(Node* head1, Node* head2) { Node* result = nullptr; Node* tail = nullptr; Node* curr1 = head1, *curr2 = head2; // Insert all elements from the first list // into the result list while (curr1 != nullptr) { if (!isPresent(result, curr1->data)) { Node* newNode = new Node(curr1->data); if (result == nullptr) { result = newNode; tail = result; } else { tail->next = newNode; tail = newNode; } } curr1 = curr1->next; } // Insert elements from the second list into the // result list if they are not already present while (curr2 != nullptr) { if (!isPresent(result, curr2->data)) { Node* newNode = new Node(curr2->data); if (result == nullptr) { result = newNode; tail = result; } else { tail->next = newNode; tail = newNode; } } curr2 = curr2->next; } return result; } // Function to find the intersection of two linked // lists using brute force Node* findIntersection(Node* head1, Node* head2) { Node* result = nullptr; Node* tail = nullptr; Node* curr1 = head1, *curr2 = head2; // For each element in the first list, check if // it is present in the second list while (curr1 != nullptr) { if (isPresent(curr2, curr1->data) && !isPresent(result, curr1->data)) { Node* newNode = new Node(curr1->data); if (result == nullptr) { result = newNode; tail = result; } else { tail->next = newNode; tail = newNode; } } curr1 = curr1->next; } return result; } void printList(Node* head) { Node* curr = head; while (curr != nullptr) { cout << curr->data << " "; curr = curr->next; } cout << endl; } int main() { // Creating two hardcoded linked lists Node* head1 = nullptr; Node* head2 = nullptr; // Insert elements into the first linked list // 10 -> 15 -> 4 -> 20 head1 = new Node(10); head1->next = new Node(15); head1->next->next = new Node(4); head1->next->next->next = new Node(20); // Insert elements into the second linked list // 8 -> 4 -> 2 -> 10 head2 = new Node(8); head2->next = new Node(4); head2->next->next = new Node(2); head2->next->next->next = new Node(10); Node* unionList = findUnion(head1, head2); Node* intersectionList = findIntersection(head1, head2); cout << "Union: "; printList(unionList); cout << "Intersection: "; printList(intersectionList); return 0; }
C // C program to find union and intersection of two // unsorted linked lists #include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node* next; }; struct Node* createNode(int x); // Function to check if a value is present in the linked list int isPresent(struct Node* head, int value) { struct Node* curr = head; while (curr != NULL) { if (curr->data == value) { return 1; } curr = curr->next; } return 0; } // Function to find the union of two linked lists struct Node* findUnion(struct Node* head1, struct Node* head2) { struct Node* result = NULL; struct Node* tail = NULL; struct Node* curr1 = head1; struct Node* curr2 = head2; // Insert all elements from the first list into the result list while (curr1 != NULL) { if (!isPresent(result, curr1->data)) { struct Node* newNode = createNode(curr1->data); if (result == NULL) { result = newNode; tail = result; } else { tail->next = newNode; tail = newNode; } } curr1 = curr1->next; } // Insert elements from the second list into the // result list if they are not already present while (curr2 != NULL) { if (!isPresent(result, curr2->data)) { struct Node* newNode = createNode(curr2->data); if (result == NULL) { result = newNode; tail = result; } else { tail->next = newNode; tail = newNode; } } curr2 = curr2->next; } return result; } // Function to find the intersection of two linked // lists using brute force struct Node* findIntersection(struct Node* head1, struct Node* head2) { struct Node* result = NULL; struct Node* tail = NULL; struct Node* curr1 = head1; struct Node* curr2 = head2; // For each element in the first list, check if it is // present in the second list while (curr1 != NULL) { if (isPresent(curr2, curr1->data) && !isPresent(result, curr1->data)) { struct Node* newNode = createNode(curr1->data); if (result == NULL) { result = newNode; tail = result; } else { tail->next = newNode; tail = newNode; } } curr1 = curr1->next; } return result; } void printList(struct Node* head) { struct Node* curr = head; while (curr != NULL) { printf("%d ", curr->data); curr = curr->next; } printf("\n"); } struct Node* createNode(int x) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = x; newNode->next = NULL; return newNode; } int main() { // Creating two hardcoded linked lists // Insert elements into the first linked list // 10 -> 15 -> 4 -> 20 struct Node* head1 = createNode(10); head1->next = createNode(15); head1->next->next = createNode(4); head1->next->next->next = createNode(20); // Insert elements into the second linked list // 8 -> 4 -> 2 -> 10 struct Node* head2 = createNode(8); head2->next = createNode(4); head2->next->next = createNode(2); head2->next->next->next = createNode(10); struct Node* unionList = findUnion(head1, head2); struct Node* intersectionList = findIntersection(head1, head2); printf("Union: "); printList(unionList); printf("Intersection: "); printList(intersectionList); return 0; }
Java // Java program to find union and intersection of two // unsorted linked lists class Node { int data; Node next; Node(int x) { data = x; next = null; } } class GfG { // Function to check if a value is present in the linked list static boolean isPresent(Node head, int value) { Node curr = head; while (curr != null) { if (curr.data == value) { return true; } curr = curr.next; } return false; } // Function to find the union of two linked lists static Node findUnion(Node head1, Node head2) { Node result = null; Node tail = null; Node curr1 = head1, curr2 = head2; // Insert all elements from the first // list into the result list while (curr1 != null) { if (!isPresent(result, curr1.data)) { Node newNode = new Node(curr1.data); if (result == null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr1 = curr1.next; } // Insert elements from the second list into the // result list if they are not already present while (curr2 != null) { if (!isPresent(result, curr2.data)) { Node newNode = new Node(curr2.data); if (result == null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr2 = curr2.next; } return result; } // Function to find the intersection of two linked // lists using brute force static Node findIntersection(Node head1, Node head2) { Node result = null; Node tail = null; Node curr1 = head1, curr2 = head2; // For each element in the first list, check if it // is present in the second list while (curr1 != null) { if (isPresent(curr2, curr1.data) && !isPresent(result, curr1.data)) { Node newNode = new Node(curr1.data); if (result == null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr1 = curr1.next; } return result; } static void printList(Node head) { Node curr = head; while (curr != null) { System.out.print(curr.data + " "); curr = curr.next; } System.out.println(); } public static void main(String[] args) { // Insert elements into the first linked list // 10 -> 15 -> 4 -> 20 Node head1 = new Node(10); head1.next = new Node(15); head1.next.next = new Node(4); head1.next.next.next = new Node(20); // Insert elements into the second linked list // 8 -> 4 -> 2 -> 10 Node head2 = new Node(8); head2.next = new Node(4); head2.next.next = new Node(2); head2.next.next.next = new Node(10); Node unionList = findUnion(head1, head2); Node intersectionList = findIntersection(head1, head2); System.out.print("Union: "); printList(unionList); System.out.print("Intersection: "); printList(intersectionList); } }
Python # Python program to find union and intersection of two # unsorted linked lists class Node: def __init__(self, x): self.data = x self.next = None # Function to check if a value is present in the linked list def isPresent(head, value): curr = head while curr is not None: if curr.data == value: return True curr = curr.next return False # Function to find the union of two linked lists def findUnion(head1, head2): result = None tail = None curr1, curr2 = head1, head2 # Insert all elements from the first list into the result list while curr1 is not None: if not isPresent(result, curr1.data): newNode = Node(curr1.data) if result is None: result = newNode tail = result else: tail.next = newNode tail = newNode curr1 = curr1.next # Insert elements from the second list into the # result list if they are not already present while curr2 is not None: if not isPresent(result, curr2.data): newNode = Node(curr2.data) if result is None: result = newNode tail = result else: tail.next = newNode tail = newNode curr2 = curr2.next return result # Function to find the intersection of two # linked lists using brute force def findIntersection(head1, head2): result = None tail = None curr1, curr2 = head1, head2 # For each element in the first list, # check if it is present in the second list while curr1 is not None: if isPresent(curr2, curr1.data) \ and not isPresent(result, curr1.data): newNode = Node(curr1.data) if result is None: result = newNode tail = result else: tail.next = newNode tail = newNode curr1 = curr1.next return result def printList(head): curr = head while curr is not None: print(curr.data, end=" ") curr = curr.next print() if __name__ == "__main__": # Creating two hardcoded linked lists # Insert elements into the first linked list # 10 -> 15 -> 4 -> 20 head1 = Node(10) head1.next = Node(15) head1.next.next = Node(4) head1.next.next.next = Node(20) # Insert elements into the second linked list # 8 -> 4 -> 2 -> 10 head2 = Node(8) head2.next = Node(4) head2.next.next = Node(2) head2.next.next.next = Node(10) unionList = findUnion(head1, head2) intersectionList = findIntersection(head1, head2) print("Union: ", end="") printList(unionList) print("Intersection: ", end="") printList(intersectionList)
C# // C# program to find union and intersection of two // unsorted linked lists using System; class Node { public int data; public Node next; public Node(int x) { data = x; next = null; } } class GfG { // Function to check if a value is present in the linked list static bool IsPresent(Node head, int value) { Node curr = head; while (curr != null) { if (curr.data == value) { return true; } curr = curr.next; } return false; } // Function to find the union of two linked lists static Node FindUnion(Node head1, Node head2) { Node result = null; Node tail = null; Node curr1 = head1, curr2 = head2; // Insert all elements from the first list into the result list while (curr1 != null) { if (!IsPresent(result, curr1.data)) { Node newNode = new Node(curr1.data); if (result == null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr1 = curr1.next; } // Insert elements from the second list into the // result list if they are not already present while (curr2 != null) { if (!IsPresent(result, curr2.data)) { Node newNode = new Node(curr2.data); if (result == null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr2 = curr2.next; } return result; } // Function to find the intersection of two // linked lists using brute force static Node FindIntersection(Node head1, Node head2) { Node result = null; Node tail = null; Node curr1 = head1, curr2 = head2; // For each element in the first list, check //if it is present in the second list while (curr1 != null) { if (IsPresent(curr2, curr1.data) && !IsPresent(result, curr1.data)) { Node newNode = new Node(curr1.data); if (result == null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr1 = curr1.next; } return result; } static void PrintList(Node head) { Node curr = head; while (curr != null) { Console.Write(curr.data + " "); curr = curr.next; } Console.WriteLine(); } static void Main(string[] args) { // Creating two hardcoded linked lists // Insert elements into the first linked list // 10 -> 15 -> 4 -> 20 Node head1 = new Node(10); head1.next = new Node(15); head1.next.next = new Node(4); head1.next.next.next = new Node(20); // Insert elements into the second linked list // 8 -> 4 -> 2 -> 10 Node head2 = new Node(8); head2.next = new Node(4); head2.next.next = new Node(2); head2.next.next.next = new Node(10); Node unionList = FindUnion(head1, head2); Node intersectionList = FindIntersection(head1, head2); Console.Write("Union: "); PrintList(unionList); Console.Write("Intersection: "); PrintList(intersectionList); } }
JavaScript // Javascript program to find union and intersection of two // unsorted linked lists class Node { constructor(x) { this.data = x; this.next = null; } } // Function to check if a value is present in the linked // list function isPresent(head, value) { let curr = head; while (curr !== null) { if (curr.data === value) { return true; } curr = curr.next; } return false; } // Function to find the union of two linked lists function findUnion(head1, head2) { let result = null; let tail = null; let curr1 = head1, curr2 = head2; // Insert all elements from the first list into the // result list while (curr1 !== null) { if (!isPresent(result, curr1.data)) { let newNode = new Node(curr1.data); if (result === null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr1 = curr1.next; } // Insert elements from the second list into the // result list if they are not already present while (curr2 !== null) { if (!isPresent(result, curr2.data)) { let newNode = new Node(curr2.data); if (result === null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr2 = curr2.next; } return result; } // Function to find the intersection of two linked lists // using brute force function findIntersection(head1, head2) { let result = null; let tail = null; let curr1 = head1, curr2 = head2; // For each element in the first list, check if it is // present in the second list while (curr1 !== null) { if (isPresent(curr2, curr1.data) && !isPresent(result, curr1.data)) { let newNode = new Node(curr1.data); if (result === null) { result = newNode; tail = result; } else { tail.next = newNode; tail = newNode; } } curr1 = curr1.next; } return result; } function printList(head) { let curr = head; while (curr !== null) { console.log(curr.data + " "); curr = curr.next; } console.log(); } // Insert elements into the first linked list // 10 -> 15 -> 4 -> 20 let head1 = new Node(10); head1.next = new Node(15); head1.next.next = new Node(4); head1.next.next.next = new Node(20); // Insert elements into the second linked list // 8 -> 4 -> 2 -> 10 let head2 = new Node(8); head2.next = new Node(4); head2.next.next = new Node(2); head2.next.next.next = new Node(10); let unionList = findUnion(head1, head2); let intersectionList = findIntersection(head1, head2); console.log("Union: "); printList(unionList); console.log("Intersection: "); printList(intersectionList);
OutputUnion: 10 15 4 20 8 2 Intersection: 10 4
Time Complexity: O(m * n) , where m and n are the length of the two Linked Lists.
Space Complexity: O(m + n)
[Optimal Approach] Using Sorting - O(nLogn + mLogm) Time and O(n + m) Space:
The idea is to sort the given lists using merge sort, then we linearly search both sorted lists to obtain the union and intersection. By Keeping two pointers (initially pointing to the first node of the respective lists) compare the node values :
- If the values are equal, add the value to both the union and intersection lists, then move both pointers to the next node.
- else if the values are not equal, insert the smaller value into the union list and move the corresponding pointer to the next node.
- If one of the pointers becomes null, traverse the remaining nodes of the other list and add them to the union list.
Please refer to Union and Intersection of Two Linked Lists Using Merge Sort for Implemenation.
[Expected Approach] Using Hashing – O(n + m) Time and O(n + m) Space:
The idea is to use HashSet to efficiently determine the union and intersection of two linked lists.
- For Intersection - By storing the elements of one list in a hash set, we can quickly check for the presence of elements from the second list to get Intersection.
- For Union - By storing the elements of both list in a hash set, we can get unique elements from both lists to get union.
Please refer to Union and Intersection of Two Linked Lists Using Hashing for Implemenation.
Similar Reads
Union and Intersection of two Linked List using Hashing Given two singly Linked Lists, create union and intersection lists that contain the union and intersection of the elements present in the given lists. Each of the two linked lists contains distinct node values.Note: The order of elements in output lists doesnât matter. Examples:Input:head1 : 10 -
10 min read
Union and Intersection of two Linked List using Merge Sort Given two singly Linked Lists, create union and intersection lists that contain the union and intersection of the elements present in the given lists. Each of the two lists contains distinct node values.Note: The order of elements in output lists doesn't matter.Examples:Input: head1: 10 -> 15 -
15+ min read
Intersection point of two Linked Lists Given two singly linked lists that merge into a single Y-shaped list. The two lists initially have distinct paths but eventually converge at a common node, forming a Y-shape, the task is to find and return the node where the two lists merge.Intersection Point of two Linked ListsThe above diagram sho
15+ min read
Union and Intersection of two Graphs Given two graphs G1 and G2, the task is to find the union and intersection of the two given graphs, i.e. (G1 ⪠G2) and (G1 ⩠G2). Examples: Input: G1 = { ("e1", 1, 2), ("e2", 1, 3), ("e3", 3, 4), ("e4", 2, 4) }, G2 = = { ("e4", 2, 4), ("e5", 2, 5), ("e6", 4, 5) }Output:G1 union G2 ise1 1 2e2 1 3e3 3
12 min read
Concatenation of two Linked lists Given two linked lists. The task is to concatenate the second list to the end of the first list.Examples:Input: list1: 10 -> 15 -> 4 -> 20, list2: 8 -> 4 -> 2 -> 10Output: 10 -> 15 -> 4 -> 20 -> 8 -> 4 -> 2 -> 10Input: list1: 1 -> 2 -> 3, list2: 4 -> 5
6 min read