🧑‍💻

Finding the Intersection Point of Two Linked Lists

Jul 18, 2024

Finding the Intersection Point of Two Linked Lists

Introduction

  • The task is to find the intersection point of two given linked lists, i.e., the first common node where the two lists converge.
  • If the two linked lists do not intersect, return null.

Problem Explanation

  • Given: Two linked lists (head1 and head2)
  • Objective: Find the first common node between the two linked lists.
  • Example: Given Linked List 1: 1 -> 2 -> 4 -> 6 -> 7 and Linked List 2: 3 -> 5 -> 6 -> 7, the intersection is at node with value 6.

Extreme Naive Solution

  1. Traverse First Linked List and Store Nodes in Memory: (1 -> 2 -> 4 -> 6 -> 7) Using Hashing
    • Use a map data structure to store each node in the first linked list.
  2. Traverse Second Linked List: (3 -> 5 -> 6 -> 7)
    • For each node, check if the node exists in the map.
    • If found, that is the intersection point.
    • If not found and you reach null, return null.

Pseudo Code

- Take a map data structure storing node and integer - Traverse first linked list (temp1 at head1), store nodes in map - Traverse second linked list (temp2 at head2) - If node found in map, return temp2 - Else traverse next node - If entire traversal completed, return null

Time and Space Complexity

  • Time Complexity: O(N1 + N2)
  • Space Complexity: O(N1) or O(N2)

Optimized Solution 1: Align Levels

  1. Compute Lengths: Compute lengths of both linked lists.
  2. Align Their Levels: Adjust the starting point of the longer list so both lists are at the same level for comparison.
  3. Traverse and Compare: Move both pointers one step at a time until they collide or until both reach null.

Pseudo Code

- Compute lengths of both linked lists (N1, N2) - Find the difference (D) - Advance the longer list by D steps - Move both pointers one step at a time until intersection point found function findIntersection(head1, head2, D): while D: longerList = longerList.next D-- while head1 != head2: head1, head2 = head1.next, head2.next return head1 if N1 > N2: return findIntersection(head1, head2, N1 - N2) else: return findIntersection(head2, head1, N2 - N1)

Optimized Solution 2: Two-pointer Approach

  1. Initialize Two Pointers: One starting at head1 and the other at head2.
  2. Simultaneous Traversal: Move each pointer one step at a time. When a pointer reaches the end, redirect it to the head of the other list.
  3. Collision at Intersection: When the pointers collide, that is the intersection point.

Pseudo Code and Implementation

- Initialize two pointers temp1 and temp2 at head1 and head2 - Traverse both lists simultaneously - If any pointer reaches null, redirect to the head of the other list - If pointers collide, return that node function getIntersectionNode(headA, headB): if headA == null or headB == null: return null temp1, temp2 = headA, headB while temp1 != temp2: temp1 = headB if temp1 == null else temp1.next temp2 = headA if temp2 == null else temp2.next return temp1

Proof of Algorithm

  • Aligned steps ensure that both traversals match up by length difference, checking all nodes for collisions.
  • If lengths are equal, they will collide or both reach null simultaneously.
  • Time Complexity: O(N1 + N2)
  • Space Complexity: O(1)

Important Edge Cases

  • Empty Lists: If either list is empty, return null.
  • Same Head (Direct Intersection): Directly compare heads for first intersection point.
  • No Intersection: Both pointers would eventually simultaneously become null.

Conclusion

  • Understanding brute force and optimized approaches is crucial.
  • Two-pointer approach is efficient both in terms of time and space.
  • Useful in technical interviews for demonstrating problem-solving and optimization techniques.

Note: Full implementation in C++, Java, Python, and JavaScript can be found in the description links. Make sure to subscribe for more algorithm discussions!