3

I have an assignment where I need to find the intersections of 2 singly-linked (singly vs singly) lists. I also have to do it for 2 doubly linked (doubly vs doubly) lists:

  • For singly linked list, I use mergeSort() to sort both lists and then compare item by item ==> O(m.log(m) + n.log(n))

  • I am confused for doubly linked lists: the same could work, but I guess there might be a faster way.

Can someone please tell me if there is a more efficient way to find the intersection of the 2 doubly linked lists? I thought maybe we could merge them and check for duplicates, but I am not sure how that would work and how efficient it would be.

Edit: Note that 'intersection' here means a shared value, not a common node. Edit: the implementation should be done without the use of hashes

lalaland
  • 379
  • 3
  • 15
  • If two doubly linked lists share any nodes then they're identical and every node intersects. For singly linked lists, if they intersect then they share the same terminal node. Measure the lengths of the two lists, move along the longer one until you're equi-distant from the end, then move in lockstep comparing pairs of nodes. – Dave Oct 02 '20 at 15:25
  • Can you please clarify what "intersection" means? Are you expecting a link from the first list to point to the same object as a link from the second list? Or are we talking about duplicate values? – Stef Oct 02 '20 at 17:34
  • @Stef I am sorry for the ambiguity. I am talking about duplicates – lalaland Oct 02 '20 at 18:10
  • Do the values fit in memory? You could use a hash for this in linear time, linear space. – Dave Oct 02 '20 at 19:27
  • @Dave I don't have access to a hash. – lalaland Oct 02 '20 at 19:40
  • @lalaland Why not? What language are you using, or what restrictions were you given? – Dave Oct 02 '20 at 19:52
  • We didn't see hash in the course yet. and we use python in the labs but in the theory, we use only pseudocode. We just learned stacks, queues, and lists. – lalaland Oct 02 '20 at 20:07
  • @chqrlie your answer is the most suitable, but I cannot use hashes, so technically I cannot accept the answer, no? – lalaland Oct 04 '20 at 21:55
  • @lalaland: if you cannot use hash tables, your approach with sorting is probably what is expected from you anyway. You can accept the answer once you are done with the project. – chqrlie Oct 04 '20 at 22:40
  • @chqrlie Thanks, I will do that. – lalaland Oct 05 '20 at 13:48

2 Answers2

1

If one of the lists is very short or substantially shorter than the other, a simple nested linear scan with complexity O(n*m) may be faster than sorting the longer list. This is the best approach for very small n or m (1 or 0).

For the general case, you cannot suppose that the lists have no duplicates, so merging the lists would not help.

The is a potentially faster way to find the intersection of 2 lists, singly or doubly linked, or more generally the intersection of 2 sets, using a hash table:

  • create an empty hash table that can hold duplicates;
  • enumerate the first list, insert each element in the hash table: O(n);
  • enumerate the second list, for each element, if it is found in the hash table, add it to the intersection and remove it from the hash table: O(m);
  • discard the hash table.

The overall time complexity is O(n+m) using O(n) extra space. An extra advantage is the lists are not modified with this approach, which might be a requirement.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Put each item in first list into a set. Ditto for second list. Take intersection of the two sets. – Marichyasana Oct 02 '20 at 07:51
  • @chqrlie Thanks for your answer with a detailed explanation, but Is there a way to not use a hash. I don't think we can use them since we didn't see them in class. Thanks – lalaland Oct 02 '20 at 18:13
  • @lalaland: if one of the lists is very short, use a simple linear lookup for each element of the small list, otherwise sorting both lists and scanning them in parallel is a good exercise and probably what you are expected to implement. – chqrlie Oct 02 '20 at 22:16
  • @chqrlie Thanks. So there is no real difference between doubly and singly linked, is that right? – lalaland Oct 02 '20 at 23:17
  • 1
    @lalaland: I dont think there is an easy way to take advantage of doubly linked lists for this exercise. Sorting the doubly linked list is quite tricky, it is simpler to sort it as a singly liked list and to reconstruct the backlinks with a final scan. – chqrlie Oct 02 '20 at 23:36
  • @chqrlie one final question: what would be the best choice array or hash tables? Thanks – lalaland Oct 06 '20 at 06:15
  • 1
    @lalaland: a hash table can be used to reduce the complexity of element lookup to **O(1)**. If you store the elements of the second list into an sorted array, the lookup operation will take **O(log(m))** so the total complexity becomes **O(m.log(m))** to sort the second array plus **O(n.log(m))** to look up the elements of the first list, combined **O((n+m).log(m))**, which is slightly better than **O(n.log(n)) + O(m.log(m))** if **n** is substantially larger than **m**. Note however that an efficient way to sort lists, is to copy the elements to an array, sort the array, and relink the list. – chqrlie Oct 06 '20 at 08:38
1

I'll expand on my comment.

Say two doubly-linked lists intersect. Then they have a node in common. Following the pointers from that node determines all nodes in both directions, so the lists have all nodes in common.

For cycle-free singly-linked lists, if they share at least one node in common, then following the pointers from that node to the end determines all subsequent nodes. This means we can find the common nodes by measuring the length of the lists, and use two pointers comparing nodes that are equi-distant from the end until you find the first pair which are equal. This is O(n) time and O(1) space.

If there is (or might be) a cycle, use Floyd's cycle-finding algorithm (also O(n) time and O(1) space) to find it. The lists share the cycle in common. If the initial nodes aren't in the cycle, proceed as before (starting equi-distant from the cycle).

Dave
  • 7,460
  • 3
  • 26
  • 39
  • Hello @dave. Thanks for your answer, but I was talking about duplicate values, not a node in common. I am sorry for the ambiguity – lalaland Oct 02 '20 at 18:11