Solving Leetcode Interviews in Seconds with AI: Intersection of Two Linked Lists
Introduction
In this blog post, we will explore how to solve the LeetCode problem "160" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
Given the heads of two singly linked-lists headA and headB, return the node at which the two lists intersect. If the two linked lists have no intersection at all, return null. For example, the following two linked lists begin to intersect at node c1: The test cases are generated such that there are no cycles anywhere in the entire linked structure. Note that the linked lists must retain their original structure after the function returns. Custom Judge: The inputs to the judge are given as follows (your program is not given these inputs): intersectVal - The value of the node where the intersection occurs. This is 0 if there is no intersected node. listA - The first linked list. listB - The second linked list. skipA - The number of nodes to skip ahead in listA (starting from the head) to get to the intersected node. skipB - The number of nodes to skip ahead in listB (starting from the head) to get to the intersected node. The judge will then create the linked structure based on these inputs and pass the two heads, headA and headB to your program. If you correctly return the intersected node, then your solution will be accepted. Example 1: Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3 Output: Intersected at '8' Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B. - Note that the intersected node's value is not 1 because the nodes with value 1 in A and B (2nd node in A and 3rd node in B) are different node references. In other words, they point to two different locations in memory, while the nodes with value 8 in A and B (3rd node in A and 4th node in B) point to the same location in memory. Example 2: Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 Output: Intersected at '2' Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B. Example 3: Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 Output: No intersection Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values. Explanation: The two lists do not intersect, so return null. Constraints: The number of nodes of listA is in the m. The number of nodes of listB is in the n. 1 <= m, n <= 3 * 104 1 <= Node.val <= 105 0 <= skipA <= m 0 <= skipB <= n intersectVal is 0 if listA and listB do not intersect. intersectVal == listA[skipA] == listB[skipB] if listA and listB intersect. Follow up: Could you write a solution that runs in O(m + n) time and use only O(1) memory?
Explanation
Here's a breakdown of the optimal approach and the Python code:
High-Level Approach:
- Determine the lengths of both linked lists.
- Align the starting pointers of the longer list to be the same distance from the potential intersection point as the shorter list. This is done by advancing the pointer of the longer list by the difference in lengths.
- Traverse both lists in parallel until the pointers meet (i.e., point to the same node). This is the intersection point. If the pointers reach the end of both lists without intersecting, return
None.
Complexity:
- Runtime: O(m + n) - We traverse both lists at most once.
- Storage: O(1) - We use a constant amount of extra space.
Code
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def getIntersectionNode(headA: ListNode, headB: ListNode) -> ListNode:
"""
Finds the intersection node of two singly linked lists.
Args:
headA: The head of the first linked list.
headB: The head of the second linked list.
Returns:
The intersection node if the lists intersect, None otherwise.
"""
lenA = 0
lenB = 0
currA = headA
currB = headB
# Calculate the lengths of the linked lists
while currA:
lenA += 1
currA = currA.next
while currB:
lenB += 1
currB = currB.next
# Reset the pointers to the heads of the lists
currA = headA
currB = headB
# Move the pointer of the longer list forward
if lenA > lenB:
for _ in range(lenA - lenB):
currA = currA.next
elif lenB > lenA:
for _ in range(lenB - lenA):
currB = currB.next
# Traverse both lists in parallel until they intersect or reach the end
while currA and currB:
if currA == currB:
return currA
currA = currA.next
currB = currB.next
return None