You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: leetcode/1129.shortest-path-with-alternating-colors.md
+45-12Lines changed: 45 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,34 +1,45 @@
1
1
# [1129. Shortest Path with Alternating Colors](https://leetcode.com/problems/shortest-path-with-alternating-colors/)
2
2
3
+
## Hints
4
+
- What if you ignore the color alternation? How would you find the shortest path?
5
+
- How can you represent the state so that you don't revisit the same node with the same previous color?
6
+
- Why do you need to track the color of the previous edge in your BFS state?
7
+
3
8
## Breakdowns
4
-
> 1. How to calculate the shortest path from 0 to `i`?
9
+
> 1. How to calculate the shortest path from `0` to `i`?
10
+
11
+
Start BFS from `0`, and maintain a distance array for each node.
5
12
6
-
Start BFS from 0, and maintain the distance array.
13
+
> 2. How to know the color of the edge for node `i`?
7
14
8
-
> 2. How to know the color of edge of node `i`?
9
-
Convert it to an adjacency list, so that we can get the color of the edge at `i`.
15
+
Convert the edge lists to two adjacency lists: one for red edges, one for blue edges.
10
16
```js
11
17
var red[i] =set(...)
12
18
var blue[i] =set(...)
13
19
```
14
20
15
21
> 3. How to alternate color along the path?
16
22
17
-
We have to record the current color along th path.
18
-
23
+
Record the color of the previous edge in the BFS state, and only traverse edges of the opposite color next.
19
24
```js
20
25
node.color=!node.color
21
26
```
22
27
23
28
> 4. How to know there is no such path?
24
29
25
-
Initialize the distance as `inf`, then it is impossible if it remains `inf` after traverse.
30
+
Initialize the distance as `inf` (or `Int.MAX_VALUE`), then if it remains `inf` after traversal, it is unreachable.
31
+
32
+
## BFS with Color State
33
+
- This is a classic BFS shortest path problem, but with an extra state: the color of the previous edge.
34
+
- The key is to treat `(node, previous color)` as the BFS state, because you can revisit the same node if you arrive via a different color.
35
+
- You need two visited arrays (or a 2D visited array): one for red, one for blue, to avoid revisiting the same node with the same color.
36
+
- This pattern is similar to other BFS problems with extra state, such as [1293. Shortest Path in a Grid with Obstacles Elimination](1293.shortest-path-in-a-grid-with-obstacles-elimination.md), where the state includes remaining eliminations.
37
+
- BFS guarantees the shortest path is found first for each state.
26
38
27
-
## BFS
28
39
```kotlin
29
40
data classMyNode(
30
41
valindex:Int,
31
-
valisRed:Boolean,
42
+
valisRed:Boolean,// true if the previous edge is red, false if blue
##[1162. As Far from Land as Possible](https://leetcode.com/problems/as-far-from-land-as-possible/)
1
+
# [1162. As Far from Land as Possible](https://leetcode.com/problems/as-far-from-land-as-possible/)
2
2
3
-
> TODO: Review the notes + implementations
3
+
## Multi-source BFS
4
+
We can enqueue all `1`s first, and then expand the level by level.
4
5
5
-
### BFS
6
-
The problem is looking for the farest water cell from the nearest land cell. We can start from the land cells and traverse the water cells to find the farest distance.
val distances =Array(n) { IntArray(n) { Int.MAX_VALUE } }
15
+
// Approach 1: We need to maintain a distance matrix.
16
+
val distances =Array(n) { IntArray(n) { Int.MAX_VALUE } }
17
+
// Approach 2: We need to avoid duplicate visit.
18
+
val visited =HashSet<Pair<Int, Int>>()
19
+
14
20
// Find the nearest land
15
21
val queue =ArrayDeque<Pair<Int, Int>>()
16
22
var hasWater =false
@@ -20,6 +26,7 @@ fun maxDistance(grid: Array<IntArray>): Int {
20
26
if (grid[i][j] ==1) {
21
27
queue.addLast(i to j)
22
28
distances[i][j] =0
29
+
visited.add(i to j)
23
30
hasLand =true
24
31
} else {
25
32
hasWater =true
@@ -28,28 +35,60 @@ fun maxDistance(grid: Array<IntArray>): Int {
28
35
}
29
36
if (!hasWater ||!hasLand) return-1
30
37
31
-
while (queue.isNotEmpty()) {
32
-
val position = queue.removeFirst()
33
-
val x = position.first
34
-
val y = position.second
35
-
if (x <0|| y <0|| x >= n || y >= n) continue
38
+
// To be continued...
39
+
}
40
+
```
41
+
42
+
- Approach 1: We use the same approach as [542. 01 Matrix](542.01-matrix.md), we can maintain a distance matrix, and the maximum distance is the answer during the update of distance during the traversal.
- Approach 2: We can use the same idea as [994. Rotting Oranges](994.rotting-orange.md) (multi-source BFS + level by level) to find the maximum distance, we enqueue all `1`s first, and then expand the level by level.
68
+
69
+
```kotlin
70
+
// Continue from the code above
71
+
while (queue.isNotEmpty()) {
72
+
val size = queue.size
73
+
repeat (size) {
74
+
val (x, y) = queue.removeFirst()
75
+
for (d in directions) {
38
76
val newX = x + d[0]
39
77
val newY = y + d[1]
40
-
if (newX >=0&& newY >=0&& newX < n && newY < n) {
41
-
val distance = abs(newX - x) + abs(newY - y)
42
-
if (distances[newX][newY] > distances[x][y] + distance) {
0 commit comments