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:16

    If we could iterate lists exactly twice, than I can provide method for determining merge point:

    • iterate both lists and calculate lengths A and B
    • calculate difference of lengths C = |A-B|;
    • start iterating both list simultaneously, but make additional C steps on list which was greater
    • this two pointers will meet each other in the merging point
    0 讨论(0)
  • 2020-12-07 07:17

    Use Map or Dictionary to store the addressess vs value of node. if the address alread exists in the Map/Dictionary then the value of the key is the answer. I did this:

    int FindMergeNode(Node headA, Node headB) {
    
    Map<Object, Integer> map = new HashMap<Object, Integer>();
    
    while(headA != null || headB != null)
    {
        if(headA != null && map.containsKey(headA.next))
        {
            return map.get(headA.next);
        }
    
        if(headA != null && headA.next != null)
        {
             map.put(headA.next, headA.next.data);
             headA = headA.next;
        }
    
        if(headB != null && map.containsKey(headB.next))
        {
            return map.get(headB.next);
        }
    
        if(headB != null && headB.next != null)
        {
            map.put(headB.next, headB.next.data);
            headB = headB.next;
        }
    }
    
    return 0;
    }
    
    0 讨论(0)
  • 2020-12-07 07:17

    You can add the nodes of list1 to a hashset and the loop through the second and if any node of list2 is already present in the set .If yes, then thats the merge node

    static int findMergeNode(SinglyLinkedListNode head1, SinglyLinkedListNode head2) {
        HashSet<SinglyLinkedListNode> set=new HashSet<SinglyLinkedListNode>();
        while(head1!=null)
        {
            set.add(head1);
            head1=head1.next;
        }
        while(head2!=null){
            if(set.contains(head2){
                return head2.data;
            }
        }
        return -1;
    }
    
    0 讨论(0)
  • 2020-12-07 07:20

    You can use a set of Nodes. Iterate through one list and add each Node to the set. Then iterate through the second list and for every iteration, check if the Node exists in the set. If it does, you've found your merge point :)

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

    I have tested a merge case on my FC9 x86_64, and print every node address as shown below:

    Head A 0x7fffb2f3c4b0
    0x214f010
    0x214f030
    0x214f050
    0x214f070
    0x214f090
    0x214f0f0
    0x214f110
    0x214f130
    0x214f150
    0x214f170
    
    
    Head B 0x7fffb2f3c4a0
    0x214f0b0
    0x214f0d0
    0x214f0f0
    0x214f110
    0x214f130
    0x214f150
    0x214f170
    

    Note becase I had aligned the node structure, so when malloc() a node, the address is aligned w/ 16 bytes, see the least 4 bits. The least bits are 0s, i.e., 0x0 or 000b. So if your are in the same special case (aligned node address) too, you can use these least 4 bits. For example when travel both lists from head to tail, set 1 or 2 of the 4 bits of the visiting node address, that is, set a flag;

    next_node = node->next;
    node = (struct node*)((unsigned long)node | 0x1UL);
    

    Note above flags won't affect the real node address but only your SAVED node pointer value.

    Once found somebody had set the flag bit(s), then the first found node should be the merge point. after done, you'd restore the node address by clear the flag bits you had set. while an important thing is that you should be careful when iterate (e.g. node = node->next) to do clean. remember you had set flag bits, so do this way

    real_node = (struct node*)((unsigned long)node) & ~0x1UL);
    real_node = real_node->next;
    node = real_node;
    

    Because this proposal will restore the modified node addresses, it could be considered as "no modification".

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

    There is no need to modify any list. There is a solution in which we only have to traverse each list once.

    1. Create two stacks, lets say stck1 and stck2.
    2. Traverse 1st list and push a copy of each node you traverse in stck1.
    3. Same as step two but this time traverse 2nd list and push the copy of nodes in stck2.
    4. Now, pop from both stacks and check whether the two nodes are equal, if yes then keep a reference to them. If no, then previous nodes which were equal are actually the merge point we were looking for.
    0 讨论(0)
提交回复
热议问题