Home > Net >  Intersection of two linked lists without duplicities
Intersection of two linked lists without duplicities

Time:11-14

Given two sorted linked lists, where the result should be intersection without duplicities.

  • Creating of new nodes is not allowed.
  • The resulting list will be composed of the elements of the original lists.

Inputs are two lists separated by empty line:

L1 -> 2 3 3 4 4 4 5

L2 -> 3 4 5 6 7

Result -> 3 4 5

I have my solution below, but creating new node in IntersectionDestruct function.

Is there any simple way how to change IntersectionDestruct function with the logic of not creating any new node?

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

def PrintLinkedList( p ):
    print( "Result:", end=" " )
    while p!=None:
        print( p.data, end=" " )
        p = p.next
    print(".")

def ReadLinkedList():
    first = None
    last = None
    r = input()
    while r!="":
        row = r.split()
        if len(row)==0:
            break
        for s in row:
            p = Node(int(s),None)
            if first==None:
                first = p
            else:
                last.next = p
            last = p
        r = input()
return first

def LLIntersection(a, b):
    head = tail = None

    while a and b:
        if a.data == b.data:
            if head is None:
                head = Node(a.data, head)
                tail = head
            else:
                tail.next = Node(a.data, tail.next)
                tail = tail.next

            a = a.next
            b = b.next

        # advance the smaller list
        elif a.data < b.data:
            a = a.next
        else:
            b = b.next
    return head    

CodePudding user response:

The only way how you can avoid Node creation for the result, is if you reuse nodes from a or b:

def LLIntersection(a, b):
  head = tail = None

  while a and b:
    if a.data == b.data:
      if head is None:
        head = a # reusing a
        tail = head
      else:
        tail.next = a  # reusing a
        tail = tail.next

      a = a.next # here a is still pointing to the next node in a
      tail.next = None  # and here we completely detach current head from a
      b = b.next

    # advance the smaller list
    elif a.data < b.data:
      a = a.next
    else:
      b = b.next
  return head

Note, this implementation doesn't properly delete nodes from the original list a for simplicity, so that after LLIntersection is run both original list a and the LLIntersection result will share the same "tail" at some point.

CodePudding user response:

Your solution doesn't actually prevent duplicates, if you have a repeated number in both lists then advancing a and b together results in them matching again and the duplicate coming through in the result.

You should instead advance them both to a new number which would prevent any duplicates.

Then just reuse the original Nodes as well by assigning a to the list and clearing its next value so it doesn't leak into the existing list.

def IntersectionUnique(a, b):
    head = tail = None

    while a and b:
        if a.data == b.data:
            if head is None:
                head = tail = a
            else:
                tail.next = a
                tail = a
            
            # Skip past all duplicates (careful for end of list!)
            while a.next and a.data == a.next.data:
                a = a.next
            while b.next and b.data == b.next.data:
                b = b.next

            # Advance to new values
            a = a.next
            b = b.next
            
            # Clear tail
            tail.next = None

        # advance the smaller list
        elif a.data < b.data:
            a = a.next
        else:
            b = b.next
    return head

As this overwrites the next values on nodes from a, walking the list from a after this will give the same as before using the function up until the first item that intersected which had its next overwritten, then will be the intersecting values only after that.

So consider it corrupted, use the return value only.

  • Related