-
Notifications
You must be signed in to change notification settings - Fork 21
/
intersection.rb
63 lines (56 loc) · 1.48 KB
/
intersection.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# CtCI 6th Edition Problem 2.7
# Intersection: Given two (singly) linked lists, determine if the two lists intersect. Return the intersecting
# node. Note that the intersection is defined based on reference, not value. That is, if the kth
# node of the first linked list is the exact same node (by reference) as the jth node of the second
# linked list, then they are intersecting.
class Node
attr_accessor :data, :next, :prev
def initialize(data)
@data = data
@next = nil
@prev = nil
end
def to_a
@next.nil? ? [data] : [data] + @next.to_a
end
end
class LinkedList
attr_accessor :length, :head, :tail
def initialize
@length = 0
@head = nil
@tail = nil
end
def add(value)
if @tail.nil?
@head = Node.new(value)
@tail = @head
else
@tail.next = Node.new(value)
@tail.next.prev = @tail
@tail = @tail.next
end
@length += 1
self
end
def to_a
@head.to_a
end
end
# Iterate through the lists storing the hash of each node in the first list in a set.
# Return the first node from the second list who's hash is already in the set, or return nil
# It loops through each list, so it is O(a + b)
def intersection(list1, list2)
current1 = list1.head
current2 = list2.head
visited = Set.new
until current1.nil?
visited << current1.hash
current1 = current1.next
end
until current2.nil?
return current2 if visited.include? current2.hash
current2 = current2.next
end
nil
end