Skip to content

Commit a647d43

Browse files
authored
avc278 - 2.07 - Javascript (#74)
1 parent 4cde04a commit a647d43

File tree

1 file changed

+119
-0
lines changed
  • JavaScript/chapter02/p07_intersection

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Intersection: Given two (singly) linked lists, determine if the two lists intersect. Return the inter­secting node.
2+
// Note that the intersection is defined based on reference, not value. That is, if the kth node of the first linked
3+
// list is the exact same node (by reference) as the jth node of the second linked list, then they are intersecting.
4+
5+
const assert = require("assert");
6+
const { LinkedListNode } = require("../../lib/avc278/linkedlist");
7+
8+
/**
9+
*
10+
* @param {LinkedListNode} A input linked list to check against
11+
* @param {LinkedListNode} B input linked list to check against
12+
* @return {LinkedListNode|null} whether the input linked lists intersect
13+
*
14+
* For this problem, we need to figure out the length of the two linked lists in order to know where the possible
15+
* intersection occurs. This is because once the two linked lists intersect, the length from the intersection to the end
16+
* of the linked list is the same. And so, when we compare the linked lists after finding the size, we can offset the
17+
* longer linked list by the difference in size. When we first reach the end in the first traversal, we can check
18+
* immediately if the two tail nodes are the same. If they are not, we can exit early and return false since we know
19+
* they don't intersect.
20+
*
21+
* Otherwise, we offset the longer of the two linked lists, and step one node at a time until we reach nodes that are
22+
* equal. At this point, we have found our intersecting node, and return the node. In terms of runtime analysis, since
23+
* we do traverse both linked lists A and B, we require O(A + B) time. Since we only store size counters, and pointers
24+
* to sections in the linked lists, we only use up O(1) additional space.
25+
*
26+
* Runtime: O(A+B)
27+
* Space: O(1)
28+
*
29+
*/
30+
const intersection = (A, B) => {
31+
if (!A || !B) return null;
32+
33+
let aSize = 1;
34+
let currA = A;
35+
while (currA.next) {
36+
aSize += 1;
37+
currA = currA.next;
38+
}
39+
40+
let bSize = 1;
41+
let currB = B;
42+
while (currB.next) {
43+
bSize += 1;
44+
currB = currB.next;
45+
}
46+
47+
if (currA !== currB) return null;
48+
49+
let smaller = aSize < bSize ? A : B;
50+
let longer = aSize < bSize ? B : A;
51+
let diff = Math.abs(aSize - bSize);
52+
53+
while (diff > 0) {
54+
longer = longer.next;
55+
diff -= 1;
56+
}
57+
58+
while (smaller !== longer) {
59+
smaller = smaller.next;
60+
longer = longer.next;
61+
}
62+
63+
return smaller;
64+
};
65+
66+
describe(module.filename, () => {
67+
it("should return false when given an empty linked list", () => {
68+
const a1 = null;
69+
const b1 = new LinkedListNode(1, null);
70+
71+
assert.ok(!intersection(a1, b1));
72+
});
73+
it("should return false when the linked lists do not intersect, even though the node values are the same.", () => {
74+
/*
75+
* a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7
76+
*
77+
* b1 -> b2 -> b3 -> b4 -> b5 -> b6
78+
*/
79+
const a7 = new LinkedListNode(7, null);
80+
const a6 = new LinkedListNode(6, a7);
81+
const a5 = new LinkedListNode(5, a6);
82+
const a4 = new LinkedListNode(4, a5);
83+
const a3 = new LinkedListNode(3, a4);
84+
const a2 = new LinkedListNode(2, a3);
85+
const a1 = new LinkedListNode(1, a2);
86+
87+
const b6 = new LinkedListNode(6, null);
88+
const b5 = new LinkedListNode(5, b6);
89+
const b4 = new LinkedListNode(4, b5);
90+
const b3 = new LinkedListNode(3, b4);
91+
const b2 = new LinkedListNode(2, b3);
92+
const b1 = new LinkedListNode(1, b2);
93+
94+
assert.ok(!intersection(a1, b1));
95+
});
96+
it("should return the intersecting node when the two linked lists intersect.", () => {
97+
/*
98+
* a1 -> a2 -> a3 -> a4
99+
* \
100+
* -> c1 -> c2 -> c3
101+
* /
102+
* b1 -> b2 -> b3
103+
*/
104+
const c3 = new LinkedListNode(7, null);
105+
const c2 = new LinkedListNode(6, c3);
106+
const c1 = new LinkedListNode(5, c2);
107+
108+
const a4 = new LinkedListNode(4, c1);
109+
const a3 = new LinkedListNode(3, a4);
110+
const a2 = new LinkedListNode(2, a3);
111+
const a1 = new LinkedListNode(1, a2);
112+
113+
const b3 = new LinkedListNode(3, c1);
114+
const b2 = new LinkedListNode(3, b3);
115+
const b1 = new LinkedListNode(3, b2);
116+
117+
assert.equal(intersection(a1, b1), c1);
118+
});
119+
});

0 commit comments

Comments
 (0)