Intersection of two single linked lists in java

[title]
Given two possibly looped and possibly acyclic single linked lists, head nodes head1 and head2, please implement a function,
If the two linked lists intersect, the first node of the intersection is returned. If they do not intersect, null is returned
[requirements]
If the total length of the two linked lists is N, the time complexity is O(N) and the space complexity is O(1)
[ideas]
The two single linked lists are divided into the following three cases. In fact, only 1 and 3 need to be considered

  1. Both single linked lists are acyclic single linked lists
    1.1. Intersection
    1.2. Disjoint
  2. Two single linked lists, one acyclic and one ring - can't intersect
  3. Two single linked lists have rings
    3.1 intersect outside the ring
    3.2 intersecting in the ring
    3.3 Disjoint

1. Judge whether the linked list has a ring and use the speed pointer
The fast pointer takes two steps at a time and the slow pointer takes one step at a time
If there is a ring, the two pointers will eventually meet. The fast pointer returns to the beginning. The fast pointer and slow pointer one node at a time. The node that meets again is the ring entry node. Just return to the ring entry node

If there is no ring, the next node or the next node of the fast pointer must be empty. Return null

public Node getLoopNode(Node head){
	//Less than 3 nodes are acyclic
   if (head == null || head.next == null 
        || head.next.next == null){
       return null;
   }
   Node slow = head.next;
   Node fast = head.next.next;
   //Get the intersection of fast and slow pointers
   while (fast != slow){
   
       //The node finally points to null, indicating acyclic
       if (fast.next == null || fast.next.next == null){
           return null;
       }
       fast = fast.next.next;
       slow = slow.next;
   }
   //The fast pointer returns to the beginning and moves at the same time as the slow pointer. Each time a node intersects, the intersection position is the ring entry point. Prove yourself to check
   fast = head;
   while (slow != fast){
       slow = slow.next;
       fast = fast.next;
   }
   return slow;
}
  1. Judge whether it is a linked list by whether the incoming node is empty
    2.1 both are acyclic linked lists. First traverse the length of the two linked lists. The length difference is dif. For the longer linked list, go through dif nodes first, and then start to go through the long and short linked lists at the same time. When you reach the same node, it is the first intersection node. If there are no equal nodes, it means no intersection
private Node getNoLoopNode(Node head1,Node head2){
	if (null == head1 || null == head2){
        return null;
    }
    //Traverse two linked lists to obtain the length difference
    Node cur1 = head1;
    Node cur2 = head2;
    int len = 0;
    while (null != cur1){
        len++;
        cur1 = cur1.next;
    }
    while (null != cur2){
        len--;
        cur2 = cur2.next;
    }

    cur1 = len >= 0 ? head1 : head2;
    cur2 = cur1 == head1 ? head2 : head1;
    len = Math.abs(len);
    while (len != 0){
        len--;
        cur1 = cur1.next;
    }
    while (cur1 != cur2){
        cur1 = cur1.next;
        cur2 = cur2.next;
    }
    return cur1;
}

2.2 there are all linked lists. There are three cases,

  • Intersect outside the ring
    If the nodes in the ring are the same, it means that they intersect outside the ring. The method of obtaining intersection nodes is the same as that of acyclic single linked list
  • They don't intersect
    If the incoming nodes are not connected, use the characteristics of whether the incoming nodes continue to traverse whether they meet to judge whether they intersect in the ring. If they do not meet, it means they do not intersect
  • Intersect on ring
    If the entry node continues to traverse and meet, it indicates that it intersects on the ring
private Node getBothLoopNode(Node head1, Node loop1, Node head2, Node loop2){
	Node cur1 = null;
    Node cur2 = null;
    //If the exchange nodes of two linked lists are the same, they must intersect outside the ring. The intersection nodes are obtained in the way of single linked list acyclic
    if (loop1 == loop2){
        cur1 = head1;
        cur2 = head2;
        int len = 0;
        while (cur1 != loop1){
            len++;
            cur1 = cur1.next;
        }
        while (cur2 != loop2){
            len--;
            cur2 = cur2.next;
        }
        cur1 = len > 0 ? head1 : head2;
        cur2 = cur1 == head1 ? head2 : head1;
        len = Math.abs(len);
        while (len != 0){
            cur1 = cur1.next;
            len--;
        }
        while (cur1 != cur2){
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        return cur1;
    } else {
        cur1 = loop1.next;
        //Traverse the ring nodes. If they meet, they intersect on the ring, otherwise they do not intersect
        while (cur1 != loop1){
            if (cur1 == loop2){
                return loop1;//loop1  or loop2
            }
            cur1 = cur1.next;
        }
        return null;
    }
}

On this topic, it is mainly clear that each node of the single linked list has only one direction. If you enter the ring, you will not leave the ring

Tags: Java Programming Algorithm data structure linked list

Posted on Thu, 14 Oct 2021 22:34:00 -0400 by Weirdan