-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path1129-shortest-path-with-alternating-colors.rb
62 lines (53 loc) · 1.64 KB
/
1129-shortest-path-with-alternating-colors.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
# frozen_string_literal: true
# 1129. Shortest Path with Alternating Colors
# https://leetcode.com/problems/shortest-path-with-alternating-colors
# @param {Integer} n
# @param {Integer[][]} red_edges
# @param {Integer[][]} blue_edges
# @return {Integer[]}
def shortest_alternating_paths(n, red_edges, blue_edges)
Graph.new(n, red_edges, blue_edges).shortest_alternating_paths
end
class Graph
def initialize(n, red_edges, blue_edges)
@n = n
@graph_data = Array.new(@n) { { r: [], b: [] } }
red_edges.each do |(from, to)|
@graph_data[from][:r] << to
end
blue_edges.each do |(from, to)|
@graph_data[from][:b] << to
end
end
def shortest_alternating_paths
queue = [[0, nil, 0]]
visited_edges = {}
result = Array.new(n) { -1 }
while (node, parent_color, length = queue.shift)
result[node] = length if result[node] == -1
(%i(r b) - [parent_color]).each do |color|
graph_data[node][color].each do |next_node|
unless visited_edges.dig(node, next_node, color)
visited_edges[node] ||= {}
visited_edges[node][next_node] ||= {}
visited_edges[node][next_node][color] = true
queue << [next_node, color, length + 1]
end
end
end
end
result
end
private
attr_reader :graph_data, :n
end
# **************** #
# TEST #
# **************** #
require "test/unit"
class Test_shortest_alternating_paths < Test::Unit::TestCase
def test_
assert_equal [0, 1, -1], shortest_alternating_paths(3, [[0, 1], [1, 2]], [])
assert_equal [0, 1, -1], shortest_alternating_paths(3, [[0, 1]], [[2, 1]])
end
end