Welcome to MSDN Blogs Sign in | Join | Help

Interesting Linked-List problem

Here's another problem which was given to me by Amit. I had lots of fun solving this :) 

image

Consider two link list as shown above which are joined at some point. The problem statement is as follows

"Given pointers to two single-linked list, find out if they are joined and at which node they are joined. Use constant space to solve this and assume that the nodes cannot be modified."

From the experience of the previous similar problem I posted let me first explain what is meant by constant space . Constant space means that the algorithm should use constant amount of space and its memory allocation should NOT increase as the length of the list increases. This means ironing out every byte allocation is a NOT a goal (constant space doesn't mean least amount of space). Just ensure that the allocation doesn't increase with the length.

Non-Solution 

The above two constrains rules out the two most common brute force algorithms that come to mind

  1. Add another bool/bit field to the nodes and while traversing the list mark the node by setting this field. Check out while traveling in second pass through the other pointer whether any node has this field set which would give the common node. There are some possible optimization over this like traversing the two lists in parallel so that not all the nodes be touched in the first pass.
  2. Create list/hash-tables of the nodes for look up later

My-Solution

I call this my solution because I'm sure there are better solutions to this :). This is O(n) solution.

The pseudo-code

  1. Traverse the first list looking for the last node and compute the list's length (say len1)
  2. Traverse the second list looking for the last node and compute it's length (say len2)
  3. The last nodes of the two list has to be the same if they have joined anywhere in the middle. If not then the lists are not joined and hence return NULL
  4. Find whichever is the longer list (using len1 and len2) and increment the root pointer of that list by abs(len1 - len2). This would ensure that both the pointers are equidistant from joined node.
  5. Make another pass through the list by incrementing both the pointers and at every step ensure if they point to the same node. Since both are equidistant from the joined node (see step 4) this check will succeed and return the joined node.

The C++ code looks something as follows

// Data-structure for the node
typedef
struct Node { Node(int pVal) { val = pVal; p = NULL; } int val; Node *p; } *PNODE; PNODE GetJoinedNode(PNODE LL1, PNODE LL2) { // handle null lists if(LL1 == NULL || LL2 == NULL) return NULL; PNODE t1 = LL1, t2 = LL2; int len1 = 1, len2 = 1; // Find first list's length and it's last node for(;t1->p != NULL; t1 = t1->p) ++len1; // find second list's length and it's last node for(;t2->p != NULL; t2 = t2->p) ++len2; // last node not same means no joins in the middle if (t1 != t2) return NULL; // Advance the longer list by the difference in length so that // the pointers are equidistant from the join PNODE* t = len1 > len2 ? &LL1 : &LL2; AdvanceBy(t, abs(len1 - len2)); // last pass to find the join. for(;LL1 != LL2; LL1 = LL1->p, LL2 = LL2->p); return LL1; } void AdvanceBy(PNODE *pNode, int val) { for(int i = 0; i < val; ++i) (*pNode) = (*pNode)->p; }
Published Thursday, August 16, 2007 10:42 AM by abhinaba
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# University Update - C# - Interesting Linked-List problem

# re: Interesting Linked-List problem

Thursday, August 16, 2007 11:17 AM by Michael

Sigh, by writing this on such a popular site, I think you might have killed this question as a good interview question.

# re: Interesting Linked-List problem

Tuesday, August 21, 2007 12:56 PM by Bruce

That's the same answer I came up with, so it must be right.  *grin*

Seriously, I'd be interested in hearing any alternate approaches.

As for using this as an interview question - if there are multiple solutions, then this is still an interesting question, for the discussion value.

# re: Interesting Linked-List problem

Thursday, August 23, 2007 3:06 AM by obiwanjacobi

My idea was to walk the link list backwards. Because I thought that when a different number of nodes precede the join (as shown in the picture) you would not compare nodes at the correct position if you walk forwards.

(refer to the picture for node numbers)

forward iteration would compare: 1-7, 2-8, 3-4, 4-5 not getting any results.

backward iteration would compare: 6-6, 5-5, 4-4, 3-8 (and return the last match)

or am I wrong...?

# re: Interesting Linked-List problem

Thursday, August 23, 2007 3:15 AM by obiwanjacobi

... I am worng ;-)

I see my mistake: its not a double linked list so you can't walk backwards. And I misread the match loop: I missed the pointer magic by the AdvanceBy method...

# re: Interesting Linked-List problem

Saturday, November 10, 2007 12:35 PM by innersmile

How about the situation that one

or both given linked lists may

contain a loop?

# re: Interesting Linked-List problem

Saturday, March 15, 2008 11:58 PM by Sandeep

One solution that can tell if they are joined or not (although doesn't tell where they are joined):

Make LL1.LastNode.Next point to LL2.FirstNode. Then run the cycle detection code (slow/fast pointer technique) on LL1. If cycle detected, they are joined. If not, they are not.

# re: Interesting Linked-List problem

Thursday, April 24, 2008 8:38 AM by Rabindra nayak

Yes backward traverse is the proper solution i think...

# re: Interesting Linked-List problem Alternate solution

Monday, September 15, 2008 3:00 AM by Ankush

calculate the address of last node (which should be same form both lists).

Now make a function that always returns a node address of node previous to the address(node) passed to it. function will get one head pointer and one address.

now in a loop

call this funtion 2 times

1 for list A by sending its head and node address

2 for list B by sending its head  and node address

(initial node address will be of last node address)

compare addresses returned by function if same then again iterate the loop and now address field will be the returned address

when ever the returned addresses mismatch that will be the joined point.

What you think am i right ?

# re: Interesting Linked-List problem

Friday, December 12, 2008 4:07 AM by Atoshi

Cant we start traversing node by node from the 2 starting point say P1 and P2 (head point for 2 linked lsit) and where we found P1-> next(address) = P2.next (address) there the linked lists join. AM not sure but this is the 1st answer came to my mind.

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker