Given two singly linked lists head1 and head2, where both lists are sorted in increasing order, find their intersection and create a new linked list containing all the common elements.
If an element occurs multiple times in both lists, it should appear in the intersection as many times as it occurs in both lists.
The original linked lists should not be modified.
Example:Â
Input: head1 = 1 -> 2 -> 3 -> 4 -> 6, head2 = 2 -> 4 -> 6 -> 8 Output: 2 -> 4-> 6 Explanation: The elements 2, 4, and 6 are common in both lists, so they appear in the intersection list.
Input: head1 = 1 -> 2 -> 2 -> 3 -> 4, head2 = 2 -> 2 -> 2 -> 4 -> 5 Output: 2 -> 2 -> 2 -> 3 -> 4 Explanation: For the given two linked list, 2, 2 and 4 are the elements in the intersection.
[Naive Approach] Search Each Node - O(n × m) Time and O(1) Auxiliary Space
The idea is to traverse the first linked list and search for each element in the second linked list. If a matching element is found, add it to the result linked list.
Traverse the first linked list.
For each node, search for its value in the second linked list.
Since both lists are sorted, stop the search when the current element in the second list becomes greater than the element being searched.
If the value is found, add it to the result linked list.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};Node*findIntersection(Node*head1,Node*head2){Node*head=nullptr;Node*tail=nullptr;// Traverse the first listwhile(head1!=nullptr){Node*curr=head2;// Search for the current value in the second listwhile(curr!=nullptr&&curr->data<head1->data){curr=curr->next;}// Add the value if it is present in both listsif(curr!=nullptr&&curr->data==head1->data){Node*newNode=newNode(head1->data);if(head==nullptr){head=newNode;tail=newNode;}else{tail->next=newNode;tail=newNode;}}head1=head1->next;}returnhead;}voidprintList(Node*head){while(head!=nullptr){cout<<head->data;if(head->next!=nullptr)cout<<" -> ";head=head->next;}cout<<endl;}intmain(){// Create the first sorted linked listNode*head1=newNode(1);head1->next=newNode(2);head1->next->next=newNode(3);head1->next->next->next=newNode(4);head1->next->next->next->next=newNode(6);// Create the second sorted linked listNode*head2=newNode(2);head2->next=newNode(4);head2->next->next=newNode(6);head2->next->next->next=newNode(8);Node*result=findIntersection(head1,head2);printList(result);return0;}
Java
classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}publicclassMain{staticNodefindIntersection(Nodehead1,Nodehead2){Nodehead=null;Nodetail=null;// Traverse the first listwhile(head1!=null){Nodecurr=head2;// Search for the current value in the second listwhile(curr!=null&&curr.data<head1.data){curr=curr.next;}// Add the value if it is present in both listsif(curr!=null&&curr.data==head1.data){NodenewNode=newNode(head1.data);if(head==null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}}head1=head1.next;}returnhead;}staticvoidprintList(Nodehead){while(head!=null){System.out.print(head.data);if(head.next!=null)System.out.print(" -> ");head=head.next;}System.out.println();}publicstaticvoidmain(String[]args){// Create the first sorted linked listNodehead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(3);head1.next.next.next=newNode(4);head1.next.next.next.next=newNode(6);// Create the second sorted linked listNodehead2=newNode(2);head2.next=newNode(4);head2.next.next=newNode(6);head2.next.next.next=newNode(8);Noderesult=findIntersection(head1,head2);printList(result);}}
Python
classNode:def__init__(self,x):self.data=xself.next=NonedeffindIntersection(head1,head2):head=Nonetail=None# Traverse the first listwhilehead1isnotNone:curr=head2# Search for the current value in the second listwhilecurrisnotNoneandcurr.data<head1.data:curr=curr.next# Add the value if it is present in both listsifcurrisnotNoneandcurr.data==head1.data:newNode=Node(head1.data)ifheadisNone:head=newNodetail=newNodeelse:tail.next=newNodetail=newNodehead1=head1.nextreturnheaddefprintList(head):whileheadisnotNone:print(head.data,end="")ifhead.nextisnotNone:print(" -> ",end="")head=head.nextprint()if__name__=="__main__":# Create the first sorted linked listhead1=Node(1)head1.next=Node(2)head1.next.next=Node(3)head1.next.next.next=Node(4)head1.next.next.next.next=Node(6)# Create the second sorted linked listhead2=Node(2)head2.next=Node(4)head2.next.next=Node(6)head2.next.next.next=Node(8)result=findIntersection(head1,head2)printList(result)
C#
usingSystem;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classProgram{staticNodefindIntersection(Nodehead1,Nodehead2){Nodehead=null;Nodetail=null;// Traverse the first listwhile(head1!=null){Nodecurr=head2;// Search for the current value in the second listwhile(curr!=null&&curr.data<head1.data){curr=curr.next;}// Add the value if it is present in both listsif(curr!=null&&curr.data==head1.data){NodenewNode=newNode(head1.data);if(head==null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}}head1=head1.next;}returnhead;}staticvoidprintList(Nodehead){while(head!=null){Console.Write(head.data);if(head.next!=null)Console.Write(" -> ");head=head.next;}Console.WriteLine();}staticvoidMain(){// Create the first sorted linked listNodehead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(3);head1.next.next.next=newNode(4);head1.next.next.next.next=newNode(6);// Create the second sorted linked listNodehead2=newNode(2);head2.next=newNode(4);head2.next.next=newNode(6);head2.next.next.next=newNode(8);Noderesult=findIntersection(head1,head2);printList(result);}}
JavaScript
classNode{constructor(x){this.data=x;this.next=null;}}functionfindIntersection(head1,head2){lethead=null;lettail=null;// Traverse the first listwhile(head1!==null){letcurr=head2;// Search for the current value in the second listwhile(curr!==null&&curr.data<head1.data){curr=curr.next;}// Add the value if it is present in both listsif(curr!==null&&curr.data===head1.data){letnewNode=newNode(head1.data);if(head===null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}}head1=head1.next;}returnhead;}functionprintList(head){while(head!==null){process.stdout.write(head.data.toString());if(head.next!==null)process.stdout.write(" -> ");head=head.next;}console.log();}// Create the first sorted linked listlethead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(3);head1.next.next.next=newNode(4);head1.next.next.next.next=newNode(6);// Create the second sorted linked listlethead2=newNode(2);head2.next=newNode(4);head2.next.next=newNode(6);head2.next.next.next=newNode(8);letresult=findIntersection(head1,head2);printList(result);
Output
2 -> 4 -> 6
[Better Approach] Using Hashing - O(n + m) Time and O(n) Auxiliary Space
The idea is to store the frequency of each element in the first linked list using a hash map. Then, traverse the second list and add an element to the result if its frequency is greater than 0 in the Hash Map.
Store the frequency of each element from the first list.
Traverse the second list.
If the current element has a remaining frequency, add it to the result and decrease its frequency.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};Node*findIntersection(Node*head1,Node*head2){unordered_map<int,int>freq;// Store the frequency of each element in the first listwhile(head1!=nullptr){freq[head1->data]++;head1=head1->next;}Node*head=nullptr;Node*tail=nullptr;// Traverse the second listwhile(head2!=nullptr){// Add the value if it has a remaining occurrenceif(freq[head2->data]>0){Node*newNode=newNode(head2->data);freq[head2->data]--;if(head==nullptr){head=newNode;tail=newNode;}else{tail->next=newNode;tail=newNode;}}head2=head2->next;}returnhead;}voidprintList(Node*head){while(head!=nullptr){cout<<head->data;if(head->next!=nullptr)cout<<" -> ";head=head->next;}cout<<endl;}intmain(){// Create the first sorted linked listNode*head1=newNode(1);head1->next=newNode(2);head1->next->next=newNode(2);head1->next->next->next=newNode(3);head1->next->next->next->next=newNode(4);// Create the second sorted linked listNode*head2=newNode(2);head2->next=newNode(2);head2->next->next=newNode(2);head2->next->next->next=newNode(4);head2->next->next->next->next=newNode(5);Node*result=findIntersection(head1,head2);printList(result);return0;}
Java
importjava.util.HashMap;classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}publicclassMain{staticNodefindIntersection(Nodehead1,Nodehead2){HashMap<Integer,Integer>freq=newHashMap<>();// Store the frequency of each element in the first listwhile(head1!=null){freq.put(head1.data,freq.getOrDefault(head1.data,0)+1);head1=head1.next;}Nodehead=null;Nodetail=null;// Traverse the second listwhile(head2!=null){// Add the value if it has a remaining occurrenceif(freq.getOrDefault(head2.data,0)>0){NodenewNode=newNode(head2.data);freq.put(head2.data,freq.get(head2.data)-1);if(head==null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}}head2=head2.next;}returnhead;}staticvoidprintList(Nodehead){while(head!=null){System.out.print(head.data);if(head.next!=null)System.out.print(" -> ");head=head.next;}System.out.println();}publicstaticvoidmain(String[]args){// Create the first sorted linked listNodehead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(2);head1.next.next.next=newNode(3);head1.next.next.next.next=newNode(4);// Create the second sorted linked listNodehead2=newNode(2);head2.next=newNode(2);head2.next.next=newNode(2);head2.next.next.next=newNode(4);head2.next.next.next.next=newNode(5);Noderesult=findIntersection(head1,head2);printList(result);}}
Python
classNode:def__init__(self,x):self.data=xself.next=NonedeffindIntersection(head1,head2):freq={}# Store the frequency of each element in the first listwhilehead1isnotNone:freq[head1.data]=freq.get(head1.data,0)+1head1=head1.nexthead=Nonetail=None# Traverse the second listwhilehead2isnotNone:# Add the value if it has a remaining occurrenceiffreq.get(head2.data,0)>0:newNode=Node(head2.data)freq[head2.data]-=1ifheadisNone:head=newNodetail=newNodeelse:tail.next=newNodetail=newNodehead2=head2.nextreturnheaddefprintList(head):whileheadisnotNone:print(head.data,end="")ifhead.nextisnotNone:print(" -> ",end="")head=head.nextprint()defmain():# Create the first sorted linked listhead1=Node(1)head1.next=Node(2)head1.next.next=Node(2)head1.next.next.next=Node(3)head1.next.next.next.next=Node(4)# Create the second sorted linked listhead2=Node(2)head2.next=Node(2)head2.next.next=Node(2)head2.next.next.next=Node(4)head2.next.next.next.next=Node(5)result=findIntersection(head1,head2)printList(result)if__name__=="__main__":main()
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classProgram{staticNodefindIntersection(Nodehead1,Nodehead2){Dictionary<int,int>freq=newDictionary<int,int>();// Store the frequency of each element in the first listwhile(head1!=null){if(freq.ContainsKey(head1.data))freq[head1.data]++;elsefreq[head1.data]=1;head1=head1.next;}Nodehead=null;Nodetail=null;// Traverse the second listwhile(head2!=null){// Add the value if it has a remaining occurrenceif(freq.ContainsKey(head2.data)&&freq[head2.data]>0){NodenewNode=newNode(head2.data);freq[head2.data]--;if(head==null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}}head2=head2.next;}returnhead;}staticvoidprintList(Nodehead){while(head!=null){Console.Write(head.data);if(head.next!=null)Console.Write(" -> ");head=head.next;}Console.WriteLine();}staticvoidMain(){// Create the first sorted linked listNodehead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(2);head1.next.next.next=newNode(3);head1.next.next.next.next=newNode(4);// Create the second sorted linked listNodehead2=newNode(2);head2.next=newNode(2);head2.next.next=newNode(2);head2.next.next.next=newNode(4);head2.next.next.next.next=newNode(5);Noderesult=findIntersection(head1,head2);printList(result);}}
JavaScript
classNode{constructor(x){this.data=x;this.next=null;}}functionfindIntersection(head1,head2){letfreq=newMap();// Store the frequency of each element in the first listwhile(head1!==null){freq.set(head1.data,(freq.get(head1.data)||0)+1);head1=head1.next;}lethead=null;lettail=null;// Traverse the second listwhile(head2!==null){// Add the value if it has a remaining occurrenceif((freq.get(head2.data)||0)>0){letnewNode=newNode(head2.data);freq.set(head2.data,freq.get(head2.data)-1);if(head===null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}}head2=head2.next;}returnhead;}functionprintList(head){while(head!==null){process.stdout.write(head.data.toString());if(head.next!==null)process.stdout.write(" -> ");head=head.next;}console.log();}functionmain(){// Create the first sorted linked listlethead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(2);head1.next.next.next=newNode(3);head1.next.next.next.next=newNode(4);// Create the second sorted linked listlethead2=newNode(2);head2.next=newNode(2);head2.next.next=newNode(2);head2.next.next.next=newNode(4);head2.next.next.next.next=newNode(5);letresult=findIntersection(head1,head2);printList(result);}main();
Output
2 -> 2 -> 4
[Expected Approach] Using Two Pointer - O(n + m) Time and O(1) Auxiliary Space
Since both linked lists are sorted, we find the common elements by traversing both simultaneously.
The idea is to maintain two pointers, one for each list. At each step, compare their values:
If both values are equal, add the value to the result list and move both pointers.
If the value in the first list is smaller, move the pointer of the first list.
Otherwise, move the pointer of the second list.
Continue until either pointer reaches the end of its list.
This works because the lists are sorted. When one value is smaller, it cannot match the current or any previous value of the other list, so we can safely move that pointer.
C++
#include<bits/stdc++.h>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};Node*findIntersection(Node*head1,Node*head2){Node*head=nullptr;Node*tail=nullptr;// Traverse both listswhile(head1!=nullptr&&head2!=nullptr){// Add the value if it is present in both listsif(head1->data==head2->data){Node*newNode=newNode(head1->data);if(head==nullptr){head=newNode;tail=newNode;}else{tail->next=newNode;tail=newNode;}head1=head1->next;head2=head2->next;}elseif(head1->data<head2->data){head1=head1->next;}else{head2=head2->next;}}returnhead;}voidprintList(Node*head){while(head!=nullptr){cout<<head->data;if(head->next!=nullptr)cout<<" -> ";head=head->next;}cout<<endl;}intmain(){// Create the first sorted linked listNode*head1=newNode(1);head1->next=newNode(2);head1->next->next=newNode(2);head1->next->next->next=newNode(3);head1->next->next->next->next=newNode(4);// Create the second sorted linked listNode*head2=newNode(2);head2->next=newNode(2);head2->next->next=newNode(2);head2->next->next->next=newNode(4);head2->next->next->next->next=newNode(5);Node*result=findIntersection(head1,head2);printList(result);return0;}
Java
classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}publicclassMain{staticNodefindIntersection(Nodehead1,Nodehead2){Nodehead=null;Nodetail=null;// Traverse both listswhile(head1!=null&&head2!=null){// Add the value if it is present in both listsif(head1.data==head2.data){NodenewNode=newNode(head1.data);if(head==null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}head1=head1.next;head2=head2.next;}elseif(head1.data<head2.data){head1=head1.next;}else{head2=head2.next;}}returnhead;}staticvoidprintList(Nodehead){while(head!=null){System.out.print(head.data);if(head.next!=null)System.out.print(" -> ");head=head.next;}System.out.println();}publicstaticvoidmain(String[]args){// Create the first sorted linked listNodehead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(2);head1.next.next.next=newNode(3);head1.next.next.next.next=newNode(4);// Create the second sorted linked listNodehead2=newNode(2);head2.next=newNode(2);head2.next.next=newNode(2);head2.next.next.next=newNode(4);head2.next.next.next.next=newNode(5);Noderesult=findIntersection(head1,head2);printList(result);}}
Python
classNode:def__init__(self,x):self.data=xself.next=NonedeffindIntersection(head1,head2):head=Nonetail=None# Traverse both listswhilehead1isnotNoneandhead2isnotNone:# Add the value if it is present in both listsifhead1.data==head2.data:newNode=Node(head1.data)ifheadisNone:head=newNodetail=newNodeelse:tail.next=newNodetail=newNodehead1=head1.nexthead2=head2.nextelifhead1.data<head2.data:head1=head1.nextelse:head2=head2.nextreturnheaddefprintList(head):whileheadisnotNone:print(head.data,end="")ifhead.nextisnotNone:print(" -> ",end="")head=head.nextprint()defmain():# Create the first sorted linked listhead1=Node(1)head1.next=Node(2)head1.next.next=Node(2)head1.next.next.next=Node(3)head1.next.next.next.next=Node(4)# Create the second sorted linked listhead2=Node(2)head2.next=Node(2)head2.next.next=Node(2)head2.next.next.next=Node(4)head2.next.next.next.next=Node(5)result=findIntersection(head1,head2)printList(result)if__name__=="__main__":main()
C#
usingSystem;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}classProgram{staticNodefindIntersection(Nodehead1,Nodehead2){Nodehead=null;Nodetail=null;// Traverse both listswhile(head1!=null&&head2!=null){// Add the value if it is present in both listsif(head1.data==head2.data){NodenewNode=newNode(head1.data);if(head==null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}head1=head1.next;head2=head2.next;}elseif(head1.data<head2.data){head1=head1.next;}else{head2=head2.next;}}returnhead;}staticvoidprintList(Nodehead){while(head!=null){Console.Write(head.data);if(head.next!=null)Console.Write(" -> ");head=head.next;}Console.WriteLine();}staticvoidMain(){// Create the first sorted linked listNodehead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(2);head1.next.next.next=newNode(3);head1.next.next.next.next=newNode(4);// Create the second sorted linked listNodehead2=newNode(2);head2.next=newNode(2);head2.next.next=newNode(2);head2.next.next.next=newNode(4);head2.next.next.next.next=newNode(5);Noderesult=findIntersection(head1,head2);printList(result);}}
JavaScript
classNode{constructor(x){this.data=x;this.next=null;}}functionfindIntersection(head1,head2){lethead=null;lettail=null;// Traverse both listswhile(head1!==null&&head2!==null){// Add the value if it is present in both listsif(head1.data===head2.data){letnewNode=newNode(head1.data);if(head===null){head=newNode;tail=newNode;}else{tail.next=newNode;tail=newNode;}head1=head1.next;head2=head2.next;}elseif(head1.data<head2.data){head1=head1.next;}else{head2=head2.next;}}returnhead;}functionprintList(head){while(head!==null){process.stdout.write(head.data.toString());if(head.next!==null)process.stdout.write(" -> ");head=head.next;}console.log();}functionmain(){// Create the first sorted linked listlethead1=newNode(1);head1.next=newNode(2);head1.next.next=newNode(2);head1.next.next.next=newNode(3);head1.next.next.next.next=newNode(4);// Create the second sorted linked listlethead2=newNode(2);head2.next=newNode(2);head2.next.next=newNode(2);head2.next.next.next=newNode(4);head2.next.next.next.next=newNode(5);letresult=findIntersection(head1,head2);printList(result);}main();