How to find the intersection of two sorted linked list
A linked list is a common data structure made of one or more than one nodes. Each node contains a value and a pointer to the previous/next node forming the chain-like structure. These nodes are stored randomly in the system's memory, which improves its space complexity compared to the array.
Understanding the problem
We get two sorted linked lists, and we need to find the intersection of the given linked lists. Here, the intersection means the common nodes' value of both linked lists. We're not allowed to make any changes to the given linked lists. Therefore, we must make a new linked list and return the head of the new linked list having common elements of the given linked list. Let's visualize this problem:
Simple solution
Suppose we get two linked lists, and the basic approach is to use their head to traverse both lists. Now start comparing the linked lists, and while traversing, we check if both the elements of the lists are equal, then we add that node to our newly created resultant list.
This resultant list stores common elements of both linked lists. We use the tail pointer to add new nodes to the resultant list by pointing them to the last node. In our resultant intersection list, the values are allocated from the next node of the dummy—(dummy. link).
#include<iostream>using namespace std;class node {public:int data;node* link;};node* add_node(node* ptr, int data) {node* temp = new node();temp->data = data;temp->link = NULL;node* end_node=ptr;if (end_node == NULL){end_node = temp;}else {while (end_node->link != NULL)end_node = end_node->link;end_node->link = temp;}return end_node;}void print_data(node* head) {if (head == NULL) {cout << "Linked List is empty" << endl;return;}node* temp_node = new node();temp_node=head;while (temp_node != NULL) {cout << temp_node->data << " ";temp_node = temp_node->link;}}node* intersection(node* a, node* b){node dummy; //temp nodenode* tail = &dummy;dummy.link = NULL;while (a != NULL && b != NULL) { //loop for traversing elementif (a->data == b->data) { //finding common elementtail=add_node((tail), a->data); //inserting it in new listtail = tail->link; //saving the addressa = a->link;b = b->link;}else if (a->data < b->data) //finding smaller elementa = a->link; //if a is smaller, traversing next nodeelseb = b->link; //if a is larger, traversing next node}return (dummy.link);}int main(){node* list1=new node();node* list2=new node();node* list3=NULL;list1 = NULL; list2=NULL;list1=add_node(list1,0);add_node(list1,2);add_node(list1,4);add_node(list1,6);cout << "Linked List 1: ";print_data(list1);list2=add_node(list2,4);add_node(list2,6);add_node(list2,7);cout << "\nLinked List 2: ";print_data(list2);list3=intersection(list1,list2);cout << "\nResultant: ";print_data(list3);}
Explanation
Here's the step-by-step explanation of the code:
Lines 43–48: We define the
intersectionfunction in which we create thedummynode that temporarily stores the node's value.Lines 50–55: We use the
whileloop to traverse bothaandblinked lists. If we get any common node between them, we insert it into thedummynode.Lines 57–62: We check whether the current element
ais smaller than the current elementband move to the next node accordingly. Finally, we return the pointer—dummy.link.
Time Complexity: O(m+n), where m and n are the numbers of nodes in the first and second linked lists, respectively.
Space Complexity: O(min(m, n)), since the output list can store at most min(m, n) nodes.
Efficient solution
We think of recursion to do this efficiently. We use the recursive function that takes two nodes and returns the intersected node list will be used instead of the traditional method.
Comparing the first two items of each list is the most efficient strategy. In this case, we call the recursive function with the next node from both lists and return a node with the common node data. Otherwise, if they are not similar, we remove the smaller node from both lists and recursively call the recursive function for the second time.
//function for finding common nodes in a and bnode* intersection(node* a, node* b){if(a==NULL || b==NULL)return NULL; //if any list is emptyif (a->data < b->data)return intersection(a->link, b); //recursion using smaller elementif (a->data > b->data)return intersection(a, b->link); //recursionnode* temp = new node();temp->data = a->data; //storing in temp nodetemp->link = intersection(a->link,b->link); //recursionreturn temp;}//driver codeint main(){node* list1=new node();node* list2=new node();node* list3=NULL;list1 = NULL; list2=NULL;list1=add_node(list1,0);add_node(list1,2);add_node(list1,4);add_node(list1,6);cout << "Linked List 1: ";print_data(list1);list2=add_node(list2,4);add_node(list2,6);add_node(list2,7);cout << "\nLinked List 2: ";print_data(list2);list3=intersection(list1,list2);cout << "\nResultant: ";print_data(list3);}
Explanation
Lines 2–5: We define the
intersectionfunction and it returnsNULLif any of the lists is empty.Lines 7–11: We find the current smaller element in both
aandband call recursively theintersectionfunction using that smaller element.Lines 13–16: We store the current value in
tempand call theintersectionfunction using recursion for the next element.
Time Complexity: O(m+n), where m and n are the numbers of nodes in the first and second linked lists, respectively.
Space Complexity: O(min(m, n)), since the output list can store at most min(m, n) nodes.
Free Resources