Bird
Raised Fist0
DSA Javascriptprogramming~15 mins

Intersection Point of Two Linked Lists in DSA Javascript - Deep Dive

Choose your learning style10 modes available
Overview - Intersection Point of Two Linked Lists
What is it?
Given two singly linked lists that may share a common tail, find the node where they first merge. Intersection means the same object reference β€” both pointers hold the exact same node object in memory, not just nodes with equal values. In JavaScript, object equality with === compares references, making this check both natural and precise.
Why it matters
JavaScript passes objects by reference, making reference identity a foundational concept for data structure manipulation, React reconciliation, and memory management. The two-pointer path-swap technique also appears in cycle detection, palindrome checking, and sliding window problems.
Where it fits
You need comfort with JavaScript objects, linked list traversal, and reference vs value equality before tackling this. After mastering it, Floyd's cycle detection, merging sorted lists, and WeakMap-based caching follow naturally.
Mental Model
Core Idea
If two runners start from different points but each runs both paths in sequence, they cover the same total distance and meet exactly where the paths merge.
Think of it like...
Two roads of different lengths merge onto one shared highway. Driver A takes road A then road B; driver B takes road B then road A. Both drive the same total distance and enter the shared highway at exactly the same moment.
List A:  1 β†’ 3 β†’ 5 ─┐
                       β”œβ†’ 8 β†’ 10 β†’ null
List B:  2 β†’ 4 β”€β”€β”€β”€β”€β”˜

pA: 1β†’3β†’5β†’8β†’10β†’null β†’ 2β†’4β†’[8] βœ“
pB: 2β†’4β†’8β†’10β†’null β†’ 1β†’3β†’5β†’[8] βœ“
Both reach the same node object {val:8} simultaneously.
Build-Up - 6 Steps
1
FoundationReference Identity in JavaScript β€” === on Objects
πŸ€”
Concept: === on objects compares references (memory addresses), not values.
In JavaScript, nodeA === nodeB is true only when both variables point to the same object in memory β€” the same heap allocation. Two separate objects {val: 8, next: null} and {val: 8, next: null} are NOT equal by === even though they look identical. Intersection detection requires reference equality (===), never value equality (nodeA.val === nodeB.val).
Result
You can reliably detect a true memory intersection using ===.
JavaScript's === on objects is always reference comparison. This makes intersection detection clean β€” no custom equality function needed, just pA === pB.
2
FoundationBrute Force β€” O(mΓ—n) Nested Loop
πŸ€”
Concept: For every node in list A, scan all of list B checking reference equality.
Outer loop traverses list A node by node. Inner loop traverses list B. If nodeA === nodeB (same reference), return that node. Time O(mΓ—n), space O(1). This is correct but slow β€” useful only to confirm that === is the right check before optimizing.
Result
Correct baseline establishing reference equality as the check.
Verifying brute force works via === locks in the correct mental model before applying the optimized path-swap.
3
IntermediateLength Difference Approach
πŸ€”Before reading on: if list A has 6 nodes and list B has 4, how many steps should the longer pointer advance before walking both in sync? Commit to your answer.
Concept: Advance the longer list's pointer by the length difference, then walk both in sync.
Count lenA and lenB with two traversals. If lenA > lenB, advance pA by (lenA - lenB) steps. Both are now equidistant from the tail. Walk both one step each iteration. First node where pA === pB is the intersection. Time O(m+n), space O(1).
Result
Efficient O(m+n) solution after tail alignment.
Once aligned at equal distance from null, the first common reference must be the intersection.
4
IntermediateTwo-Pointer Path-Swap Technique
πŸ€”Before reading on: if pA traverses list A then list B, and pB traverses list B then list A, do both cover the same total number of nodes? Commit yes or no.
Concept: When a pointer reaches null, redirect it to the head of the other list.
Initialize pA = headA, pB = headB. Each step advance both. When pA === null, set pA = headB. When pB === null, set pB = headA. Continue until pA === pB. Both traverse lenA + lenB nodes total, arriving at the intersection simultaneously. If no intersection, both reach null together.
Result
Elegant O(m+n) time, O(1) space with no length variables.
lenA + lenB === lenB + lenA. The path swap exploits this arithmetic symmetry to cancel the starting offset without any measurement.
5
AdvancedNo Intersection β€” null === null in JavaScript
πŸ€”Before reading on: in JavaScript, does null === null evaluate to true? Commit yes or no.
Concept: Both pointers become null simultaneously when no intersection exists, terminating the loop.
If no intersection exists, after each pointer traverses both lists, pA === null and pB === null at the same step. In JavaScript, null === null is true, so pA !== pB evaluates to false and the while loop exits cleanly. Return null.
Result
No special case or counter needed β€” the same loop handles both cases.
null === null is true in JavaScript (null is a primitive, not an object). The termination condition works universally without any extra flag.
6
ExpertSet Approach β€” Space Tradeoff with JavaScript Set
πŸ€”Before reading on: can you store all node references from list A in a JavaScript Set and check list B against it? What is the space cost? Commit to your answer.
Concept: Store all node objects from list A in a Set, then scan list B.
const visited = new Set(). Traverse list A adding each node object: visited.add(node). Then traverse list B β€” first node where visited.has(node) is true is the intersection. Time O(m+n), space O(m). JavaScript's Set uses reference identity by default for objects β€” no custom equality needed. Simpler to implement but uses extra memory.
Result
Correct O(m+n) solution at O(m) space cost.
JavaScript Set uses SameValueZero algorithm for object membership, which is effectively === for objects β€” it stores and checks references, not values.
Under the Hood
The path-swap works because pA travels lenA + lenB nodes and pB travels lenB + lenA nodes β€” identical totals. If an intersection exists at distance d from null, both arrive at that node after lenA + lenB - d steps. The different starting positions contribute lenA and lenB to each pointer's first leg and lenB and lenA to the second β€” the offset cancels exactly.
Why designed this way?
JavaScript linked lists are object chains with no built-in length. Computing lengths requires traversal. The path-swap avoids explicit length computation by exploiting symmetry: a + b === b + a. This mirrors Floyd's cycle detection β€” two pointers with mathematically guaranteed convergence replace brute comparison.
Step trace (A: 1β†’3β†’5β†’8β†’10, B: 2β†’4β†’8β†’10):

Step  pA            pB
  0    {val:1}       {val:2}
  1    {val:3}       {val:4}
  2    {val:5}       {val:8}
  3    {val:8}       {val:10}
  4    {val:10}      null→headA
  5    null→headB    {val:1}
  6    {val:2}       {val:3}
  7    {val:4}       {val:5}
  8    {val:8}==={val:8}  ← same object βœ“
Myth Busters - 4 Common Misconceptions
Quick: does nodeA.val === nodeB.val confirm intersection in JavaScript? Commit yes or no.
Common Belief:Two nodes intersect if their val properties are equal.
Tap to reveal reality
Reality:Intersection requires nodeA === nodeB (same object reference). Two separate objects with identical val are not the same node.
Why it matters:Comparing .val instead of references produces false positives on any list with duplicate values β€” a subtle JavaScript bug that produces no error, just wrong output.
Quick: does null === null evaluate to true in JavaScript? Commit yes or no.
Common Belief:null === null might be false because null is a special value.
Tap to reveal reality
Reality:null === null is true in JavaScript. null is a primitive β€” strict equality on two nulls always returns true.
Why it matters:Doubting this leads to adding unnecessary loop counters or break conditions, adding complexity and potential off-by-one bugs.
Quick: does JavaScript Set use deep equality to check object membership? Commit yes or no.
Common Belief:JavaScript Set compares objects by their content (deep equality) when checking membership.
Tap to reveal reality
Reality:Set uses SameValueZero, which for objects is reference equality. Two distinct objects with identical properties are treated as different Set entries.
Why it matters:Expecting deep equality from Set leads to incorrect intersection detection β€” you would miss the intersection or get false positives depending on the bug.
Quick: does the path-swap loop run forever when no intersection exists? Commit yes or no.
Common Belief:The loop runs infinitely because redirects keep happening between the two lists.
Tap to reveal reality
Reality:After each pointer traverses both lists, both become null simultaneously. null !== null is false so the loop exits cleanly.
Why it matters:Adding a manual step counter to prevent 'infinite loops' is unnecessary and can incorrectly terminate the loop before finding the intersection.
Expert Zone
1
The path-swap requires exactly one redirect per pointer. A second redirect breaks distance symmetry β€” the pointers would travel different total distances and never meet at the intersection.
2
If both lists have equal length, the pointers stay naturally synchronized from step one and the first common reference is found without any redirect.
3
JavaScript's garbage collector tracks object references. Nodes in the intersected tail are referenced by both lists β€” they will not be collected until both list heads are released.
When NOT to use
If lists may contain cycles, pointers never reach null and the redirect never fires β€” detect and break cycles first. If using value objects (plain data without shared references), the === check will always fail β€” use a WeakMap keyed by a unique ID property instead.
Production Patterns
Reference intersection detection appears in React's reconciliation (detecting shared component instances), JavaScript VM heap analysis (aliased object detection), and graph algorithm libraries (shared node detection in DAGs). The path-swap principle generalizes to any two-sequence synchronization where a shared suffix must be located efficiently.
Connections
Floyd's Cycle Detection
Both use two-pointer synchronization with mathematically guaranteed meeting points rather than brute comparison.
Mastering intersection detection makes Floyd's algorithm intuitive β€” both problems reduce to: move two pointers with specific rules and they will meet at a meaningful reference.
JavaScript Set and Reference Equality
Set membership for objects uses reference equality (SameValueZero β‰ˆ ===), making it natural for storing and checking node references.
Understanding that Set stores references, not copies, is the key insight that makes the hash set approach work correctly without any custom equality logic.
React Reconciliation
React's diffing algorithm checks whether component instances are the same object reference to decide between update and remount.
The reference identity concept mastered here directly explains why React uses keys and object identity to detect which list items changed.
Common Pitfalls
#1Comparing .val instead of object references.
Wrong approach:while (pA && pB) { if (pA.val === pB.val) // WRONG β€” value comparison return pA; pA = pA.next; pB = pB.next; }
Correct approach:while (pA !== pB) { // Correct β€” reference comparison pA = pA ? pA.next : headB; pB = pB ? pB.next : headA; } return pA;
Root cause:In JavaScript, === on objects is reference comparison, not value comparison. Using .val comparison produces wrong answers on any list with duplicate node values.
#2Redirecting after advancing past null, skipping headB's first node.
Wrong approach:pA = pA.next; if (pA === null) { pA = headB; pA = pA.next; // WRONG β€” skips headB }
Correct approach:pA = pA ? pA.next : headB; // Redirect is part of the ternary advance, not a separate post-step
Root cause:Separating the null check from the advance causes the first node of the redirected list to be skipped, breaking distance symmetry by exactly one step.
#3Using Set with .has() on a value copy instead of the original node reference.
Wrong approach:// Storing copies breaks reference tracking const visited = new Set(); let curr = headA; while (curr) { visited.add({...curr}); // WRONG β€” adds a copy, not the original curr = curr.next; }
Correct approach:const visited = new Set(); let curr = headA; while (curr) { visited.add(curr); // Correct β€” adds the original reference curr = curr.next; }
Root cause:Spreading an object creates a new object with a different reference. Set.has() will never find it because it checks the original reference, not property values.
Key Takeaways
Intersection means the same object reference (pA === pB in JavaScript), not equal values β€” never compare .val for intersection detection.
The path-swap two-pointer technique equalizes total traversal distance so both pointers arrive at the intersection simultaneously without computing list lengths.
null === null is true in JavaScript β€” both pointers reaching null simultaneously terminates the loop cleanly when no intersection exists.
JavaScript Set uses reference equality for objects by default β€” add original node references directly, never spread or copy them.
Exactly one redirect per pointer is required β€” a second redirect breaks distance symmetry and causes incorrect results.

Practice

(1/5)
1. What does the term Intersection Point of Two Linked Lists mean?
easy
A. The node where two linked lists merge and share the same next nodes
B. The first node of the longer linked list
C. The last node of the shorter linked list
D. The node with the highest value in both lists

Solution

  1. Step 1: Understand linked list structure

    Linked lists are chains of nodes where each node points to the next node.
  2. Step 2: Define intersection point

    The intersection point is where two lists share the exact same node object, meaning from that node onward, both lists are identical.
  3. Final Answer:

    The node where two linked lists merge and share the same next nodes -> Option A
  4. Quick Check:

    Intersection means shared node = D [OK]
Hint: Intersection means shared node reference, not just value [OK]
Common Mistakes:
  • Thinking intersection means same value, not same node
  • Confusing intersection with concatenation
  • Assuming intersection is always at head
2. Which of the following JavaScript code snippets correctly initializes two linked lists that intersect at node with value 8?
easy
A. const list1 = { val: 3, next: { val: 8, next: null } }; const list2 = { val: 7, next: { val: 8, next: null } };
B. const intersectNode = { val: 8, next: null }; const list1 = { val: 3, next: intersectNode }; const list2 = { val: 7, next: intersectNode };
C. const list1 = { val: 3, next: null }; const list2 = { val: 7, next: null };
D. const intersectNode = { val: 8, next: null }; const list1 = { val: 3, next: { val: 8, next: null } }; const list2 = { val: 7, next: intersectNode };

Solution

  1. Step 1: Check for shared node reference

    const intersectNode = { val: 8, next: null }; const list1 = { val: 3, next: intersectNode }; const list2 = { val: 7, next: intersectNode }; creates one node object for value 8 and both lists point to it, ensuring intersection.
  2. Step 2: Compare other options

    const list1 = { val: 3, next: { val: 8, next: null } }; const list2 = { val: 7, next: { val: 8, next: null } }; creates two separate nodes with value 8, no intersection. const list1 = { val: 3, next: null }; const list2 = { val: 7, next: null }; has no intersection node. const intersectNode = { val: 8, next: null }; const list1 = { val: 3, next: { val: 8, next: null } }; const list2 = { val: 7, next: intersectNode }; has list1 pointing to a new node, not the shared one.
  3. Final Answer:

    shares the same node object for intersection -> Option B
  4. Quick Check:

    Shared node object = A [OK]
Hint: Intersection requires same node object, not just same value [OK]
Common Mistakes:
  • Creating separate nodes with same value instead of shared node
  • Not linking both lists to the intersecting node
  • Confusing node value with node reference
3. Given the following code, what will be the output of console.log(getIntersectionNode(listA, listB)?.val || null);?
function getIntersectionNode(headA, headB) {
  let a = headA, b = headB;
  while (a !== b) {
    a = a ? a.next : headB;
    b = b ? b.next : headA;
  }
  return a;
}

const intersect = { val: 5, next: { val: 6, next: null } };
const listA = { val: 1, next: { val: 2, next: intersect } };
const listB = { val: 9, next: { val: 4, next: intersect } };
medium
A. 5
B. null
C. 6
D. 1

Solution

  1. Step 1: Understand the algorithm

    The function uses two pointers that traverse both lists; when they meet, that node is the intersection.
  2. Step 2: Identify intersection node

    Both lists share the node with value 5, so the function returns that node.
  3. Final Answer:

    5 -> Option A
  4. Quick Check:

    Intersection node value = 5 [OK]
Hint: Two-pointer method returns intersection node or null [OK]
Common Mistakes:
  • Expecting value 6 instead of 5
  • Confusing node value with list head value
  • Not understanding pointer switching logic
4. The following code attempts to find the intersection node of two linked lists but may cause infinite loop when there is no intersection. What is the bug?
function getIntersectionNode(headA, headB) {
  let a = headA, b = headB;
  while (a !== b) {
    a = a.next || headB;
    b = b.next || headA;
  }
  return a;
}
medium
A. The function should return b instead of a
B. The loop condition should be 'while(a && b && a !== b)'
C. The pointers should not switch lists
D. Using 'a.next || headB' incorrectly jumps to headB when a.next is null

Solution

  1. Step 1: Analyze pointer update logic

    Using 'a.next || headB' sets a to headB when a.next is null (while a points to last node), skipping null handling and causing infinite loops when no intersection.
  2. Step 2: Correct pointer switching

    The correct approach is to check if 'a' is null, then switch to headB; otherwise, move to a.next.
  3. Final Answer:

    Using 'a.next || headB' causes skipping headB when a.next is null -> Option D
  4. Quick Check:

    Pointer update must check 'a' null, not 'a.next' [OK]
Hint: Check pointer null before moving to next list head [OK]
Common Mistakes:
  • Using 'a.next || headB' instead of 'a ? a.next : headB'
  • Not handling null pointers correctly
  • Returning wrong pointer at end
5. You have two singly linked lists that intersect. List A length is 7, List B length is 5. How can you find the intersection point efficiently?
hard
A. Reverse both lists and compare from the start
B. Traverse both lists fully and compare node values to find intersection
C. Advance the longer list by difference in lengths, then move both pointers together until they meet
D. Use a hash set to store all values of the shorter list, then check values of the longer list

Solution

  1. Step 1: Calculate length difference

    Find lengths of both lists; difference is 2 (7 - 5).
  2. Step 2: Advance longer list pointer

    Move pointer of longer list ahead by 2 nodes to align both lists equally from intersection point.
  3. Step 3: Move both pointers together

    Traverse both lists simultaneously until pointers are equal, which is the intersection node.
  4. Final Answer:

    Advance longer list by difference in lengths, then move both pointers together until they meet -> Option C
  5. Quick Check:

    Align pointers by length difference = A [OK]
Hint: Align list starts by length difference before simultaneous traversal [OK]
Common Mistakes:
  • Comparing node values instead of node references
  • Not aligning pointers before traversal
  • Using extra space unnecessarily
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard