Site Search:

OverlapDetection.java


import java.util.HashSet;
import java.util.Set;

public class OverlapDetection {
    static LNode loopHead;
    public static void main(String...args) {
        LNode head1 = createLinkedList1();
        LNode head2 = createLinkedList2();
        printResult(head1);
        System.out.println();
        printResult(head2);
        System.out.println();
        System.out.println("hasOverlapBrutalForce: " + hasOverlapBrutalForce(head1, head2));
        head1 = createLinkedList1();
        head2 = createLinkedList2();
        System.out.println("hasOverlapSlowFastPointer: " + hasOverlapSlowFastPointer(head1, head2));
        head1 = createLinkedList1();
        head2 = createLinkedList2();
        System.out.println("hasOverlapCommonTail: " + hasOverlapSlowFastPointer(head1, head2));
    }
    
    public static boolean hasOverlapBrutalForce(LNode head1, LNode head2) {
        if(head1 == null || head1.next == null ||
                head2 == null || head2.next == null) return false;
        Set<LNode> visited = new HashSet<>();
        LNode current = head1.next;
        while(current != null) {
            visited.add(current);
            current = current.next;
        }
        current = head2.next;
        while(current != null) {
            if(visited.contains(current))
                return true;
            current = current.next;
        }
        return false;
    }
    
    public static boolean hasOverlapSlowFastPointer(LNode head1, LNode head2) {
        if(head1 == null || head1.next == null ||
                head2 == null || head2.next == null) return false;
        LNode current = head1.next;
        while(current.next != null) {
            current = current.next;
        }
        //link the first linked list's tail to the head of the second linked list.
        current.next = head2;
        
        LNode slowPointer = head2.next;
        LNode fastPointer = head2.next;
        while(fastPointer != null && fastPointer.next != null) {
            slowPointer = slowPointer.next;
            fastPointer = fastPointer.next.next;
            if(slowPointer == fastPointer) return true;
        }
        return false;
    }
    
    public static boolean hasOverlapCommonTail(LNode head1, LNode head2) {
        if(head1 == null || head1.next == null ||
                head2 == null || head2.next == null) return false;
        LNode current = head1.next;
        while(current.next != null) {
            current = current.next;
        }
        LNode tail1 = current;
        current = head2.next;
        while(current.next != null) {
            current = current.next;
        }
        return tail1 == current;
    }
    
    public static LNode createLinkedList1() {
        LNode head = new LNode(0, null);
        LNode current = new LNode(1, null);
        head.next = current;
        current.next = new LNode(2, null);
        current = current.next;
        current.next = new LNode(3, null);
        current = current.next;
        current.next = new LNode(4, null);
        current = current.next;
        loopHead = current;
        current.next = new LNode(5, null);
        current = current.next;
        current.next = new LNode(6, null);
        current = current.next;
        current.next = new LNode(7, null);
        return head;
    }
    
    public static LNode createLinkedList2() {
        LNode head = new LNode(0, null);
        LNode current = new LNode(11, null);
        head.next = current;
        current.next = new LNode(22, null);
        current = current.next;
        current.next = new LNode(33, null);
        current = current.next;
        current.next = loopHead;
        return head;
    }
    
    public static void printResult(LNode head) {
        System.out.println();
        if(head == null || head.next == null) return;
        LNode current = head.next;
        while(current != null) {
            System.out.print(current.value + " ");
            current = current.next;
        }
    }

}