Skip to content

Commit cecffb5

Browse files
committedFeb 1, 2023
feat: add solutions to lc problem: No.1129
No.1129.Shortest Path with Alternating Colors
1 parent 4fc7b37 commit cecffb5

File tree

6 files changed

+271
-318
lines changed

6 files changed

+271
-318
lines changed
 

‎solution/1100-1199/1129.Shortest Path with Alternating Colors/README.md

+103-106
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,25 @@
6767

6868
**方法一:BFS**
6969

70+
题目实际上是最短路问题,我们可以考虑使用 BFS 来解决。
71+
72+
首先,我们对所有的边进行预处理,将所有的边按照颜色分类,存储到多维数组 $g$ 中。其中 $g[0]$ 存储所有红色边,而 $g[1]$ 存储所有蓝色边。
73+
74+
接着,我们定义以下数据结构或变量:
75+
76+
- 队列 $q$:用来存储当前搜索到的节点,以及当前边的颜色;
77+
- 集合 $vis$:用来存储已经搜索过的节点,以及当前边的颜色;
78+
- 变量 $d$:用来表示当前搜索的层数,即当前搜索到的节点到起点的距离;
79+
- 数组 $ans$:用来存储每个节点到起点的最短距离。初始时,我们将 $ans$ 数组中的所有元素初始化为 $-1$,表示所有节点到起点的距离都未知。
80+
81+
我们首先将起点 $0$ 和起点边的颜色 $0$ 或 $1$ 入队,表示从起点出发,且当前是红色或蓝色边。
82+
83+
接下来,我们开始进行 BFS 搜索。我们每次从队列中取出一个节点 $(i, c)$,如果当前节点的答案还未更新,则将当前节点的答案更新为当前层数 $d$,即 $ans[i] = d$。然后,我们将当前边的颜色 $c$ 取反,即如果当前边为红色,则将其变为蓝色,反之亦然。我们取出颜色对应的所有边,如果边的另一端节点 $j$ 未被搜索过,则将其入队。
84+
85+
搜索结束后,返回答案数组即可。
86+
87+
时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别为节点数和边数。
88+
7089
<!-- tabs:start -->
7190

7291
### **Python3**
@@ -78,31 +97,26 @@ class Solution:
7897
def shortestAlternatingPaths(
7998
self, n: int, redEdges: List[List[int]], blueEdges: List[List[int]]
8099
) -> List[int]:
81-
red = defaultdict(list)
82-
blue = defaultdict(list)
100+
g = [defaultdict(list), defaultdict(list)]
83101
for i, j in redEdges:
84-
red[i].append(j)
102+
g[0][i].append(j)
85103
for i, j in blueEdges:
86-
blue[i].append(j)
87-
vis_blue = [False] * n
88-
vis_red = [False] * n
89-
q = deque([(0, True), (0, False)])
104+
g[1][i].append(j)
90105
ans = [-1] * n
91-
d = -1
106+
vis = set()
107+
q = deque([(0, 0), (0, 1)])
108+
d = 0
92109
while q:
93-
d += 1
94110
for _ in range(len(q)):
95-
i, b = q.popleft()
96-
if ans[i] == -1 or ans[i] > d:
111+
i, c = q.popleft()
112+
if ans[i] == -1:
97113
ans[i] = d
98-
vis = vis_blue if b else vis_red
99-
vis[i] = True
100-
ne = red[i] if b else blue[i]
101-
v = vis_red if b else vis_blue
102-
for j in ne:
103-
if not v[j]:
104-
v[j] = True
105-
q.append((j, not b))
114+
vis.add((i, c))
115+
c ^= 1
116+
for j in g[c][i]:
117+
if (j, c) not in vis:
118+
q.append((j, c))
119+
d += 1
106120
return ans
107121
```
108122

@@ -113,48 +127,42 @@ class Solution:
113127
```java
114128
class Solution {
115129
public int[] shortestAlternatingPaths(int n, int[][] redEdges, int[][] blueEdges) {
116-
List<Integer>[] red = get(n, redEdges);
117-
List<Integer>[] blue = get(n, blueEdges);
118-
boolean[] visBlue = new boolean[n];
119-
boolean[] visRed = new boolean[n];
130+
List<Integer>[][] g = new List[2][n];
131+
for (var f : g) {
132+
Arrays.setAll(f, k -> new ArrayList<>());
133+
}
134+
for (var e : redEdges) {
135+
g[0][e[0]].add(e[1]);
136+
}
137+
for (var e : blueEdges) {
138+
g[1][e[0]].add(e[1]);
139+
}
120140
Deque<int[]> q = new ArrayDeque<>();
121-
q.offer(new int[] {0, 1});
122141
q.offer(new int[] {0, 0});
123-
int d = -1;
142+
q.offer(new int[] {0, 1});
143+
boolean[][] vis = new boolean[n][2];
124144
int[] ans = new int[n];
125145
Arrays.fill(ans, -1);
146+
int d = 0;
126147
while (!q.isEmpty()) {
127-
++d;
128-
for (int t = q.size(); t > 0; --t) {
129-
int[] p = q.poll();
130-
int i = p[0];
131-
boolean b = p[1] == 1;
132-
if (ans[i] == -1 || ans[i] > d) {
148+
for (int k = q.size(); k > 0; --k) {
149+
var p = q.poll();
150+
int i = p[0], c = p[1];
151+
if (ans[i] == -1) {
133152
ans[i] = d;
134153
}
135-
boolean[] vis = b ? visBlue : visRed;
136-
vis[i] = true;
137-
List<Integer> ne = b ? red[i] : blue[i];
138-
boolean[] v = b ? visRed : visBlue;
139-
for (int j : ne) {
140-
if (!v[j]) {
141-
v[j] = true;
142-
q.offer(new int[] {j, 1 - p[1]});
154+
vis[i][c] = true;
155+
c ^= 1;
156+
for (int j : g[c][i]) {
157+
if (!vis[j][c]) {
158+
q.offer(new int[] {j, c});
143159
}
144160
}
145161
}
162+
++d;
146163
}
147164
return ans;
148165
}
149-
150-
private List<Integer>[] get(int n, int[][] edges) {
151-
List<Integer>[] res = new List[n];
152-
Arrays.setAll(res, k -> new ArrayList<>());
153-
for (int[] e : edges) {
154-
res[e[0]].add(e[1]);
155-
}
156-
return res;
157-
}
158166
}
159167
```
160168

@@ -164,92 +172,81 @@ class Solution {
164172
class Solution {
165173
public:
166174
vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& redEdges, vector<vector<int>>& blueEdges) {
167-
vector<vector<int>> red = get(n, redEdges);
168-
vector<vector<int>> blue = get(n, blueEdges);
169-
vector<bool> visBlue(n);
170-
vector<bool> visRed(n);
171-
queue<pair<int, bool>> q;
172-
q.push({0, true});
173-
q.push({0, false});
174-
int d = -1;
175+
vector<vector<vector<int>>> g(2, vector<vector<int>>(n));
176+
for (auto& e : redEdges) {
177+
g[0][e[0]].push_back(e[1]);
178+
}
179+
for (auto& e : blueEdges) {
180+
g[1][e[0]].push_back(e[1]);
181+
}
182+
queue<pair<int, int>> q;
183+
q.emplace(0, 0);
184+
q.emplace(0, 1);
185+
bool vis[n][2];
186+
memset(vis, false, sizeof vis);
175187
vector<int> ans(n, -1);
188+
int d = 0;
176189
while (!q.empty()) {
177-
++d;
178-
for (int t = q.size(); t > 0; --t) {
179-
auto p = q.front();
190+
for (int k = q.size(); k; --k) {
191+
auto [i, c] = q.front();
180192
q.pop();
181-
int i = p.first;
182-
bool b = p.second;
183-
if (ans[i] == -1 || ans[i] > d) ans[i] = d;
184-
vector<bool>& vis = b ? visBlue : visRed;
185-
vis[i] = true;
186-
vector<int>& ne = b ? red[i] : blue[i];
187-
vector<bool>& v = b ? visRed : visBlue;
188-
for (int j : ne) {
189-
if (v[j]) continue;
190-
v[j] = true;
191-
q.push({j, !b});
193+
if (ans[i] == -1) {
194+
ans[i] = d;
195+
}
196+
vis[i][c] = true;
197+
c ^= 1;
198+
for (int& j : g[c][i]) {
199+
if (!vis[j][c]) {
200+
q.emplace(j, c);
201+
}
192202
}
193203
}
204+
++d;
194205
}
195206
return ans;
196207
}
197-
198-
vector<vector<int>> get(int n, vector<vector<int>>& edges) {
199-
vector<vector<int>> res(n);
200-
for (auto& e : edges) res[e[0]].push_back(e[1]);
201-
return res;
202-
}
203208
};
204209
```
205210
206211
### **Go**
207212
208213
```go
209214
func shortestAlternatingPaths(n int, redEdges [][]int, blueEdges [][]int) []int {
210-
get := func(edges [][]int) [][]int {
211-
res := make([][]int, n)
212-
for _, e := range edges {
213-
res[e[0]] = append(res[e[0]], e[1])
214-
}
215-
return res
215+
g := [2][][]int{}
216+
for i := range g {
217+
g[i] = make([][]int, n)
218+
}
219+
for _, e := range redEdges {
220+
g[0][e[0]] = append(g[0][e[0]], e[1])
216221
}
217-
red := get(redEdges)
218-
blue := get(blueEdges)
219-
visBlue := make([]bool, n)
220-
visRed := make([]bool, n)
221-
q := [][]int{{0, 1}, {0, 0}}
222+
for _, e := range blueEdges {
223+
g[1][e[0]] = append(g[1][e[0]], e[1])
224+
}
225+
type pair struct{ i, c int }
226+
q := []pair{pair{0, 0}, pair{0, 1}}
222227
ans := make([]int, n)
228+
vis := make([][2]bool, n)
223229
for i := range ans {
224230
ans[i] = -1
225231
}
226-
d := -1
232+
d := 0
227233
for len(q) > 0 {
228-
d++
229-
for t := len(q); t > 0; t-- {
234+
for k := len(q); k > 0; k-- {
230235
p := q[0]
231236
q = q[1:]
232-
i := p[0]
233-
b := p[1] == 1
234-
if ans[i] == -1 || ans[i] > d {
237+
i, c := p.i, p.c
238+
if ans[i] == -1 {
235239
ans[i] = d
236240
}
237-
vis := visRed
238-
ne := blue[i]
239-
v := visBlue
240-
if b {
241-
vis = visBlue
242-
ne = red[i]
243-
v = visRed
244-
}
245-
vis[i] = true
246-
for _, j := range ne {
247-
if !v[j] {
248-
v[j] = true
249-
q = append(q, []int{j, 1 - p[1]})
241+
vis[i][c] = true
242+
c ^= 1
243+
for _, j := range g[c][i] {
244+
if !vis[j][c] {
245+
q = append(q, pair{j, c})
250246
}
251247
}
252248
}
249+
d++
253250
}
254251
return ans
255252
}

0 commit comments

Comments
 (0)