# 2.7. Intersection > Given 2 singly linked lists, determine if the 2 lists intersect. Return the intersecting node. The intersection is defined based on the reference, not value. If the kth node of the first linked list is the exact same node (by reference) as the jth node of the second linked list, then True ## Initial idea Two nodes in a singly linked list are similar by reference (?) if all values about the object are the same, right? That is, if `.next` and `.data` are the same. ```java public static LinkedListNode intersect(LinkedListNode a, LinkedListNode b){ while(a != null && b != null){ if(a.data == b.data && a.next.data == b.next.data){ return a; } a = a.next; b = b.next; } return null; } ``` how to evaluate if `a.next == b.next`? because `a.next == c`, and c on itself has `c.next`, and so on. Changing by `a.next.data == b.next.data` ## Hint 1 > You can do this in O(A + B) time and O(1) additional space, no need to use a hash table The previous code doesn't compare all nodes... I should do a nested loop, then it'd be O(AB). ```java public static LinkedListNode intersect(LinkedListNode a, LinkedListNode b){ LinkedListNode b_reset = b; while(a != null){ b = b_reset; while(b != null){ if(a.data == b.data && a.next.data == b.next.data){ return a; } b = b.next; } a = a.next; } return null; } ``` Still far away from O(A + B). We cannot iterate A and B at the same time then? How can we compare them? ## Hint 2 > Draw a picture of intersecting linked lists and two equivalent linked lists (by value) that don't intersect. Problem is, I don't understand what by value and by reference are. ## Hint 3 > Focus first on just identifying if there's an intersection An intersection is two nodes having the same `.data`? ## Hint 4 > Two intersecting linked lists always have the same last node. Once they intersect, all the nodes after that will be equal Ok, this follows my previous idea that `.next` must also be equal, which means `.next.next` also, until the end. We can iterate to the last node of the list, check if they match, and then find the diverting node. How to find the diverting node is another topic ```java public static LinkedListNode intersect(LinkedListNode a, LinkedListNode b){ while(a.next != null){ a = a.next; } while(b.next != null){ b = b.next; } if(a.data == b.data){ // do things LinkedListNode ane = null; return ane; } return null; } ``` ## Hint 5 > You can determine if two linked lists intersect by traversing to the end of each and comparing their tails Gotcha ## Hint 6 > Now need to find the intersection, how to do this if len(A) == len(B)? Ideally I would iterate backwards, but that's not possible... Maybe with two pointers. What about: 1. Iterate through both 2. If `a.data == b.data`, save `a`. 3. Keep checking the condition. If it's not met, reset. 4. If `a.data == b.data`, save `a`. 5. Reach the end, with saved `a` node. Of course, they need to have the same length. This would be O(3A) time and O(1) space. ```java public static LinkedListNode intersect(LinkedListNode a, LinkedListNode b){ LinkedListNode a_head = a; LinkedListNode b_head = b; // iterate through A while(a_head.next != null){ a_head = a_head.next; } // iterate through B while(b_head.next != null){ b_head = b_head.next; } // last node inequal, return null if(a_head.data != b_head.data) return null; // there's intersection LinkedListNode inters = null; while(a.next != null && b.next != null){ // nodes with same data found if(a.data == b.data){ // no intersecting node, set to a if(inters == null){ inters = a; } // if nodes are sme and reset = true, keep iterating } // nodes aren't the same, reset inters else{ inters = null; } a = a.next; b = b.next; } if(inters == null) return a; return inters; } ``` This should work, in the worst case the intersecting node is the tail itself. If they have a different length: 1. Get both lengths 2. Get minimum length, and advance the pointer of the longest list minlen positions. Then start algorithm ```java public static LinkedListNode intersect(LinkedListNode a, LinkedListNode b){ LinkedListNode a_head = a; LinkedListNode b_head = b; int a_len, b_len = 1; // iterate through A while (a_head.next != null){ a_head = a_head.next; a_len += 1; } // iterate through B while (b_head.next != null){ b_head = b_head.next; b_len += 1; } // last node inequal, return null if (a_head.data != b_head.data) return null; // compare lengths, adjust node if (a_len == 1 or b_len == 1) return a_head; if (a_len < b_len){ while (a_len > 0){ b = b.next; } } else if (b_len < a_len){ while (b_len > 0){ a = a.next; } } // there's intersection LinkedListNode inters = null; while(a.next != null && b.next != null){ // nodes with same data found if(a.data == b.data){ // no intersecting node, set to a if(inters == null){ inters = a; } // if nodes are sme and reset = true, keep iterating } // nodes aren't the same, reset inters else{ inters = null; } a = a.next; b = b.next; } if(inters == null) return a; return inters; } ``` And this should work for lists of all possible lengths. ## Hint 7 > If the two linked lists had the same length, you could trasverse forward in each until you found an element in common. How do you adjust this for lists of different lengths? Get the length difference, move the pointer of the longer one minlen times. ## Hint 8 > Try using the difference between the lengths of the two linked lists Yep. ## Hint 9 > If you move a pointer in the longer linked list forward by the difference in lengths, you can then apply a similar approach to the scenario when the linked lists are equal. Already got that. ## Solution The algorithm is the same as mine 1. Get lengths and tails of each list 2. Compare the tails, if they are different (**by reference, not by value**) return null 3. Set two pointers to the start 4. On the longer linked list, advance its pointer by the difference in lengths 5. Trasverse on each linked list until the pointers are the same Takeaways: * `size++` is possible in java, no `size += 1` necessary * When comparing nodes, compare `a == b`, not `a.data == b.data` * Get a new class for the tail and lengths Improved algorithm in **2.7. intersection.java**. Because we're comparing by reference not value, the condition in `while` won't be met if two nodes have the same `.data` but different `.next`. ## Update New solution found [at stackoverflow](https://stackoverflow.com/questions/1594061/check-if-two-linked-lists-merge-if-so-where/14956113#14956113), without any pointers.