-
Notifications
You must be signed in to change notification settings - Fork 0
/
1129.shortest-path-with-alternating-colors.py
111 lines (107 loc) · 3.01 KB
/
1129.shortest-path-with-alternating-colors.py
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#
# @lc app=leetcode.cn id=1129 lang=python3
#
# [1129] 最长字符串链
#
# https://leetcode-cn.com/problems/shortest-path-with-alternating-colors/description/
#
# algorithms
# Medium (35.89%)
# Total Accepted: 4.5K
# Total Submissions: 12.4K
# Testcase Example: '3\n[[0,1],[1,2]]\n[]'
#
# 在一个有向图中,节点分别标记为 0, 1, ..., n-1。这个图中的每条边不是红色就是蓝色,且存在自环或平行边。
#
# red_edges 中的每一个 [i, j] 对表示从节点 i 到节点 j 的红色有向边。类似地,blue_edges 中的每一个 [i, j]
# 对表示从节点 i 到节点 j 的蓝色有向边。
#
# 返回长度为 n 的数组 answer,其中 answer[X] 是从节点 0 到节点 X
# 的红色边和蓝色边交替出现的最短路径的长度。如果不存在这样的路径,那么 answer[x] = -1。
#
#
#
# 示例 1:
#
# 输入:n = 3, red_edges = [[0,1],[1,2]], blue_edges = []
# 输出:[0,1,-1]
#
#
# 示例 2:
#
# 输入:n = 3, red_edges = [[0,1]], blue_edges = [[2,1]]
# 输出:[0,1,-1]
#
#
# 示例 3:
#
# 输入:n = 3, red_edges = [[1,0]], blue_edges = [[2,1]]
# 输出:[0,-1,-1]
#
#
# 示例 4:
#
# 输入:n = 3, red_edges = [[0,1]], blue_edges = [[1,2]]
# 输出:[0,1,2]
#
#
# 示例 5:
#
# 输入:n = 3, red_edges = [[0,1],[0,2]], blue_edges = [[1,0]]
# 输出:[0,1,1]
#
#
#
#
# 提示:
#
#
# 1 <= n <= 100
# red_edges.length <= 400
# blue_edges.length <= 400
# red_edges[i].length == blue_edges[i].length == 2
# 0 <= red_edges[i][j], blue_edges[i][j] < n
#
#
#
class Solution:
def shortestAlternatingPaths(self, n: int, red_edges: List[List[int]], blue_edges: List[List[int]]) -> List[int]:
red_d,blue_d = {},{}
for start,end in red_edges:
if start not in red_d:
red_d[start] = [end]
else:
red_d[start].append(end)
for start,end in blue_edges:
if start not in blue_d:
blue_d[start] = [end]
else:
blue_d[start].append(end)
path = [float('inf')] * n
path_len = 0
red_node = [0]
blue_node = [0]
r_visited = set()
b_visited = set()
while float('inf') in path:
prv = r_visited.copy()
brv = b_visited.copy()
for n in red_node:
path[n] = min(path[n],path_len)
r_visited.add(n)
for n in blue_node:
path[n] = min(path[n],path_len)
b_visited.add(n)
new_blue_end = []
for n in red_node:
new_blue_end += blue_d.get(n,[])
new_red_end = []
for n in blue_node:
new_red_end += red_d.get(n,[])
red_node = list(set(new_red_end))
blue_node = list(set(new_blue_end))
path_len += 1
if prv == r_visited and brv == b_visited:
break
path = [l if l!=float('inf') else -1 for l in path]
return path