Start learning free

LESSON 433 OF 673 · LINKED LISTS

Intersection of Two Linked Lists in O(m + n) Time Complexity using Python

Practice O(n) Read the full explanation

You get headA and headB, the heads of two singly linked lists. Return the first node that both lists share, or None if they never join.

Two lists join at a node when both go on through the very same nodes, to the end.

In this picture, A has two nodes of its own and B has three. Then both go through c1, c2 and c3. The answer is c1:

A B a1 a2 b1 b2 b3 c1 c2 c3

What matters is the node itself, not its value. Two different nodes can hold the same number.

Neither list has a loop. Both lists must stay exactly as they were after your function returns.

The examples write out each list in full. They also give shared, the number of nodes at the end that are in both lists. It is 0 when the lists don't join.

The tests use shared to build the lists. Your function gets only headA and headB.

 

Example 1:

A B 3 5 5 9 4

Input: listA = [3,5,9,4], listB = [5,9,4], shared = 2
Output: the node with value 9
Explanation: The green nodes, 9 -> 4, are in both lists.
Each list also has a 5, but they are two different nodes.
So the first shared node is the 9.

Example 2:

A B 8 2 6 1 7 3

Input: listA = [8,3], listB = [2,6,1,7,3], shared = 1
Output: the node with value 3
Explanation: Only the last node, the green 3, is shared.
A has 1 node before it, and B has 4.

Example 3:

A B 6 2 8 4 1

Input: listA = [6,2,8], listB = [4,1], shared = 0
Output: None
Explanation: No node is in both lists.

 

Constraints:

  • Each list has 1 to 30,000 nodes.
  • Each list has at least one node of its own, before the shared part.
  • Each value is from 1 to 100,000.

 

Follow up: Can you find the node in O(m + n) time and O(1) extra memory? Here m and n are the two lengths.
STEP 1 OF 17
    Ctrl + Enter to check

    PYTHON · LINKED LISTS

    Intersection Of Two Linked Lists in Python, explained

    Understanding the Problem

    The core challenge of this problem is to identify the node at which two singly linked lists intersect. This is a common problem in linked list manipulation and has applications in various fields such as network routing, version control systems, and more. A potential pitfall is assuming that the lists intersect at the same position from the start, which is not necessarily true.

    Approach

    To solve this problem, we can use the following approaches:

    Naive Approach

    The naive approach involves using two nested loops to compare each node of the first list with each node of the second list. This approach has a time complexity of O(m * n), which is not optimal for large lists.

    Optimized Approach

    We can optimize the solution by using two pointers. The idea is to traverse both lists and switch to the other list once the end is reached. This way, both pointers will traverse the same number of nodes and meet at the intersection point if there is one.

    Algorithm

    Here is a step-by-step breakdown of the optimized algorithm:

    1. Initialize two pointers, pA and pB, to the heads of headA and headB respectively.
    2. Traverse the lists with the pointers. When a pointer reaches the end of a list, switch it to the head of the other list.
    3. If the lists intersect, the pointers will meet at the intersection node. If they do not intersect, both pointers will eventually be null.

    Code Implementation

    Here is the Python code for the optimized solution:

    class ListNode:
        def __init__(self, x):
            self.val = x
            self.next = None
    
    def getIntersectionNode(headA, headB):
        # Initialize two pointers
        pA, pB = headA, headB
        
        # Traverse the lists
        while pA != pB:
            # If pA reaches the end, switch to headB
            pA = pA.next if pA else headB
            # If pB reaches the end, switch to headA
            pB = pB.next if pB else headA
        
        # Either both pointers meet at the intersection node or both are null
        return pA
    

    Complexity Analysis

    The time complexity of this approach is O(m + n), where m and n are the lengths of the two linked lists. The space complexity is O(1) since we are using only two pointers.

    Edge Cases

    Potential edge cases include:

    • One or both lists are empty.
    • The lists do not intersect.
    • The intersection occurs at the head of one or both lists.

    These cases are handled by the algorithm as it ensures that both pointers traverse the same number of nodes.

    Testing

    To test the solution comprehensively, consider the following test cases:

    • Lists with no intersection.
    • Lists with intersection at various positions.
    • Lists with different lengths.

    Using a testing framework like unittest in Python can help automate and validate these test cases.

    Thinking and Problem-Solving Tips

    When approaching such problems, consider the following tips:

    • Understand the problem requirements and constraints thoroughly.
    • Think about different approaches and their trade-offs.
    • Optimize for time and space complexity where possible.
    • Practice solving similar problems to improve problem-solving skills.

    Conclusion

    In this blog post, we discussed the problem of finding the intersection of two linked lists. We explored a naive approach and an optimized approach using two pointers. The optimized solution runs in O(m + n) time and uses O(1) space. Understanding and solving such problems is crucial for improving algorithmic thinking and coding skills.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with Python650+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free