Check if two linked lists merge. If so, where?

后端 未结 26 1386
陌清茗
陌清茗 2020-12-07 06:43

This question may be old, but I couldn\'t think of an answer.

Say, there are two lists of different lengths, merging at a point; how do we know wher

相关标签:
26条回答
  • 2020-12-07 07:22

    Step 1: find lenght of both the list Step 2 : Find the diff and move the biggest list with the difference Step 3 : Now both list will be in similar position. Step 4 : Iterate through list to find the merge point

    //Psuedocode
    def findmergepoint(list1, list2):
    lendiff = list1.length() > list2.length() : list1.length() - list2.length() ? list2.lenght()-list1.lenght()
    biggerlist = list1.length() > list2.length() : list1 ? list2  # list with biggest length
    smallerlist = list1.length() < list2.length() : list2 ? list1 # list with smallest length
    
    
    # move the biggest length to the diff position to level both the list at the same position
    for i in range(0,lendiff-1):
        biggerlist = biggerlist.next
    #Looped only once.  
    while ( biggerlist is not None and smallerlist is not None ):
        if biggerlist == smallerlist :
            return biggerlist #point of intersection
    
    
    return None // No intersection found
    
    0 讨论(0)
  • 2020-12-07 07:24

    If

    • by "modification is not allowed" it was meant "you may change but in the end they should be restored", and
    • we could iterate the lists exactly twice

    the following algorithm would be the solution.

    First, the numbers. Assume the first list is of length a+c and the second one is of length b+c, where c is the length of their common "tail" (after the mergepoint). Let's denote them as follows:

    x = a+c
    y = b+c
    

    Since we don't know the length, we will calculate x and y without additional iterations; you'll see how.

    Then, we iterate each list and reverse them while iterating! If both iterators reach the merge point at the same time, then we find it out by mere comparing. Otherwise, one pointer will reach the merge point before the other one.

    After that, when the other iterator reaches the merge point, it won't proceed to the common tail. Instead will go back to the former beginning of the list that had reached merge-point before! So, before it reaches the end of the changed list (i.e. the former beginning of the other list), he will make a+b+1 iterations total. Let's call it z+1.

    The pointer that reached the merge-point first, will keep iterating, until reaches the end of the list. The number of iterations it made should be calculated and is equal to x.

    Then, this pointer iterates back and reverses the lists again. But now it won't go back to the beginning of the list it originally started from! Instead, it will go to the beginning of the other list! The number of iterations it made should be calculated and equal to y.

    So we know the following numbers:

    x = a+c
    y = b+c
    z = a+b
    

    From which we determine that

    a = (+x-y+z)/2
    b = (-x+y+z)/2
    c = (+x+y-z)/2
    

    Which solves the problem.

    0 讨论(0)
  • 2020-12-07 07:25

    The following is by far the greatest of all I have seen - O(N), no counters. I got it during an interview to a candidate S.N. at VisionMap.

    Make an interating pointer like this: it goes forward every time till the end, and then jumps to the beginning of the opposite list, and so on. Create two of these, pointing to two heads. Advance each of the pointers by 1 every time, until they meet. This will happen after either one or two passes.

    I still use this question in the interviews - but to see how long it takes someone to understand why this solution works.

    0 讨论(0)
  • 2020-12-07 07:29

    Well, if you know that they will merge:

    Say you start with:

    A-->B-->C
            |
            V
    1-->2-->3-->4-->5
    

    1) Go through the first list setting each next pointer to NULL.

    Now you have:

    A   B   C
    
    1-->2-->3   4   5
    

    2) Now go through the second list and wait until you see a NULL, that is your merge point.

    If you can't be sure that they merge you can use a sentinel value for the pointer value, but that isn't as elegant.

    0 讨论(0)
  • 2020-12-07 07:29

    Maybe I am over simplifying this, but simply iterate the smallest list and use the last nodes Link as the merging point?

    So, where Data->Link->Link == NULL is the end point, giving Data->Link as the merging point (at the end of the list).

    EDIT:

    Okay, from the picture you posted, you parse the two lists, the smallest first. With the smallest list you can maintain the references to the following node. Now, when you parse the second list you do a comparison on the reference to find where Reference [i] is the reference at LinkedList[i]->Link. This will give the merge point. Time to explain with pictures (superimpose the values on the picture the OP).

    You have a linked list (references shown below):

    A->B->C->D->E

    You have a second linked list:

    1->2->

    With the merged list, the references would then go as follows:

    1->2->D->E->

    Therefore, you map the first "smaller" list (as the merged list, which is what we are counting has a length of 4 and the main list 5)

    Loop through the first list, maintain a reference of references.

    The list will contain the following references Pointers { 1, 2, D, E }.

    We now go through the second list:

    -> A - Contains reference in Pointers? No, move on
    -> B - Contains reference in Pointers? No, move on
    -> C - Contains reference in Pointers? No, move on
    -> D - Contains reference in Pointers? Yes, merge point found, break.
    

    Sure, you maintain a new list of pointers, but thats not outside the specification. However the first list is parsed exactly once, and the second list will only be fully parsed if there is no merge point. Otherwise, it will end sooner (at the merge point).

    0 讨论(0)
  • 2020-12-07 07:34

    If editing the linked list is allowed,

    1. Then just make the next node pointers of all the nodes of list 2 as null.
    2. Find the data value of the last node of the list 1. This will give you the intersecting node in single traversal of both the lists, with "no hi fi logic".
    0 讨论(0)
提交回复
热议问题