'Function only outputs the last node but not the merged list + Linked List

Here is my approach when merge two linked lists:

def merge(self, l1, l2):
 cur = Node() #Creating a dummy node

 while l1 and l2:
  if l1.val <= l2.val:
   cur.next = l1
   l1 = l1.next
  else:
   cur.next = l2
   l2 = l2.next

#Skipped a block here to keep it short, not related to the question

 return cur.next

But the function only returns the last node instead of merging, and when I add a pointer to it, it does the right thing:

def merge(self, l1, l2):
 cur = Node() #Creating a dummy node
 p = cur #Pointer

 while l1 and l2:
  if l1.val <= l2.val:
   p.next = l1
   l1 = l1.next
  else:
   p.next = l2
   l2 = l2.next

return cur.next

Can someone explain? I can't seem to understand the purpose of using a pointer here. Many thanks!



Solution 1:[1]

Neither of the merge is correct they extract elements till both of them are having elements what if either l1 or l2 finishes them remaining elements will be unmerged.

In the below approach we are just moving around cur.next when we return curr.next it will be the last Node since we are setting this vlaue only either through cur.next = l1 or cur.next = l2 because of this the below approach will get only last Node.

 while l1 and l2:
  if l1.val <= l2.val:
   cur.next = l1
   l1 = l1.next
  else:
   cur.next = l2
   l2 = l2.next

#Skipped a block here to keep it short, not related to the question

 return cur.next

Merge:

def merge(l1, l2):
    start = None
    curr = None

    arr = list()
    
    while l1 or l2:
        if l1:
            arr.append(l1.val)
            l1 = l1.next
        elif l2:
            arr.append(l2.val)
            l2 = l2.next
    arr = sorted(arr)
    for val in arr:
        if curr:
            curr.next = Node(val = val)
            curr = curr.next
        else:
            curr = Node(val = val)
            start = curr
    return start 

Source:

class Node:
    def __init__(self, val = None, nextN = None):
        self.next = nextN
        self.val = val 

def merge(l1, l2):
    start = None
    curr = None

    arr = list()

    while l1 or l2:
        if l1:
            arr.append(l1.val)
            l1 = l1.next
        elif l2:
            arr.append(l2.val)
            l2 = l2.next
    arr = sorted(arr)
    for val in arr:
        if curr:
            curr.next = Node(val = val)
            curr = curr.next
        else:
            curr = Node(val = val)
            start = curr
    return start 

def printLink(node):
    temp = node
    while temp!= None :
        print(temp.val, end = '-')
        temp = temp.next
    print()


node1 = Node(val = 1)
node1.next = Node(val = 3)
node2 = node1.next
node2.next = Node(val = 4)


node2 = Node(val = 1)
node2.next = Node(val = 3)
node3 = node2.next
node3.next = Node(val = 8)
node3.next.next = Node(val = 5)

printLink(node1)
printLink(node2)

printLink(merge(node1, node2))

Solution 2:[2]

The problem with both code snippets, is that in the loop you attach the node (either l1 or l2) to the same next attribute, over and over again. So each iteration overwrites the attribute value that was determined by the previous iteration.

In each iteration you need to move the reference to the next node -- the one that was just assigned to next.

The second snippet is slightly better, as it foresees that you need two references: one to remain at the dummy node, and the other one that walks forward as nodes are assigned to next attributes.

Some other remarks:

  • Use more indentation. It is common practice to use 4 spaces for each indentation.
  • Use descriptive variable names. If a node is a dummy node, why not call it dummy?

So:

def merge(self, l1, l2):
    dummy = Node()
    current = dummy
    
    while l1 and l2:
        if l1.val <= l2.val:
            current.next = l1
            l1 = l1.next
        else:
            current.next = l2
            l2 = l2.next
        current = current.next  # This was missing!

    # Attach the remainder (either l1 or l2)
    current.next = l1 or l2

    return dummy.next

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 trincot