简体   繁体   中英

Intersection of two linked lists

给定两个排序的链表L1和L2,这是计算它们的交点L1交点L2的解决方案。

L1_node = L1.head;
L2_node = L2.head;
Result = new SList;
while L1_node != NULL and L2_node != NULL:
  if L1_node.value == L2_node.value:
     Result.append(L1_node.value)
     L1_node = L1_node.next
     L2_node = L2_node.next
  elif L1_node.value < L2_node.value:
     L1_node = L1_node.next
  else
     L2_node = L2_node.next

(Translate to C yourself.)

Since they are singly linked lists if the two linked lists intersect they would form a Y shape with one arm longer or equal to the other. Let l1 be the length of L1 list and l2 be the length of L2 list.

Suppose that l1 > l2. Start matching the pointers of List L1 from point (l1-l2) and list L2 from its beginning where ever they point to the same node that node will be the matching point.

If l2 is greater than l1 then do the other way.

How about the solution below, it is O(n+m) and takes a dummy node which is pointing to the Head node. The Head node is a class level variable here, so even if L1 is pointing to the current, Head always has the full list.

I have compiled and tested, runs fine for simple inputs like L1: 1->5>6>7>8>10 and L2:2>4>6>8 , output is 6>8

Any ideas about how to go with unsorted lists? I couldnt think of a O(n) solution

public Node ReturnIntersection(Node Head, Node L2) { if ((Head == null) || (L2 == null)) return null;

     Node temp = null;
      Node L1 = Head;


      while (L1.next != null && L2.next != null)
      {
          if (L1.data == L2.data)
          {
              L1 = L1.next;
              L2 = L2.next;
          }

          else if (L1.data < L2.data)
          {
              temp = L1.next;
              L1.data = temp.data;
              L1.next = temp.next;

          }

          else if (L1.data > L2.data)
          {
              L2 = L2.next;

          }

      }

      if (L1 != null)
      {
          while (L1.next != null)
          {
              L1.next = null;

          }
      }
      return Head;


  }

The basic approach to in-order merge-like algorithms is that you never need to consider more than three items at a time - the front items from each input list, plus potentially a saved result.

In this case, I'd use...

loop forever
  while in1.value < in2.value : transfer item from in1 to output
  while in2.value < in1.value : transfer item from in2 to output

  if in1.value == in2.value :
    transfer item from in1 to output
    discard item from in2

    while in1.value == value just transferred : disard item from in1
    while in2.value == value just transferred : disard item from in2

Now the nasty - this loop assumes the lists are infinite. How do you handle empty lists? That's fiddly, unless you can reserve a sentinel value which is greater than any legal value that can occur in the list.

If you can't reserve a sentinel, you can fake the effect - write a compare function that checks whether there's a next item in each queue before comparing values, and treats "queue exhausted" as implying the sentinel value.

That gives...

loop forever
  while in1.value < in2.value : discard item from in1
  while in2.value < in1.value : discard item from in2

  if in1 exhausted, break out of loop
  if in2 exhausted, break out of loop

  if in1.value == in2.value :
    transfer item from in1 to output
    discard item from in2

    while in1.value == value just transferred : discard item from in1
    while in2.value == value just transferred : discard item from in2

OOPS

This is a union. Converting to an intersection is left as an exercise for the reader.

EDIT

OK - it is now an intersection. Just discarding the less-than items rather than adding them to the output. Also fixed a typo.

Note - my interpretation was that the output of an intersection should be a set, meaning no duplicates. This tolerates duplicates in the inputs, but the output is duplicate-free.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM