0% completed
Problem Statement
You have a directed graph with n nodes labeled from 0 to n-1. The graph has two types of edges: red and blue. You are given two arrays redEdges and blueEdges:
redEdges[i] = [ai, bi]means there's a red edge from nodeaito nodebi.blueEdges[j] = [uj, vj]means there's a blue edge from nodeujto nodevj.
Find the shortest path from node 0 to each node x such that the edges alternate in colors. If there is no such path, return -1 for that node.
Return an array answer of length n, where answer[x] is the length of the shortest alternating path from node 0 to node x.
Examples
Example 1:
- Input: n = 4, redEdges = [[0, 1], [1, 2], [2, 3]], blueEdges = [[0, 2], [2, 1], [1, 3]]
- Expected Output: [0, 1, 1, 2]
- Justification:
- Node
0is the start, so distance is0. - Shortest path to node
1is directly from0using red edge. - Shortest path to node
2is directly from0using blue edge. - Shortest path to node
3is via node1using red then blue edge.
- Node
Example 2:
- Input: n = 3, redEdges = [[0, 1]], blueEdges = [[2, 1]]
- Expected Output: [0, 1, -1]
- Justification:
- Node
0is the start, so distance is0. - Shortest path to node
1is directly from0using red edge. - Node
2is not reachable from node0with alternating colors.
- Node
Example 3:
- Input: n = 5, redEdges = [[0, 1], [1, 3]], blueEdges = [[1, 2], [3, 4]]
- Expected Output: [0, 1, 2, -1, -1]
- Justification:
- Node
0is the start, so distance is0. - Shortest path to node
1is directly from0using red edge. - Shortest path to node
2is via node1using red then blue edge. - Shortest path to node
3is via node1using red edge, but not with alternative colors. - Shortest path to node
4is via node3using red then blue edge, but not with alternative colors.
- Node
Constraints:
- 1 <= n <= 100
- 0 <= redEdges.length, blueEdges.length <= 400
- redEdges[i].length == blueEdges[j].length == 2
- 0 <= ai, bi, uj, vj < n
Solution
To solve this problem, we can use a Breadth-First Search (BFS) approach because it helps find the shortest path in an unweighted graph. BFS explores all possible paths layer by layer, ensuring the shortest path is found. Here, we need to keep track of the colors of the edges to ensure the paths alternate colors. We can use a queue to explore each node, alternating the colors as we go. By maintaining a visited status for each node with both red and blue colors, we ensure we do not revisit nodes in an invalid manner, preventing cycles and redundant paths.
This approach ensures that we check all possible paths from the starting node, considering color alternations. It's efficient since BFS operates in O(V + E) time complexity, where V is the number of vertices and E is the number of edges. Given the graph's constraints, this is an optimal solution.
Step-by-Step Algorithm
-
Initialize Data Structures:
- Create two adjacency lists for the graph: one for red edges and one for blue edges.
- Initialize a 2D result array
reswith size[2][n], filled withInteger.MAX_VALUE, to store the shortest path lengths. Set the starting node0distance to0for both colors (i.e.,res[0][0] = 0andres[1][0] = 0).
-
Build Graph:
- For each red edge
[ai, bi]inredEdges, addbito the adjacency list ofaiin the red graph. - For each blue edge
[uj, vj]inblueEdges, addvjto the adjacency list ofujin the blue graph.
- For each red edge
-
Initialize BFS Queue:
- Create a queue to store the nodes along with the color of the last edge used to reach them. Initialize the queue with the starting node
0for both red and blue edges (i.e.,queue.add({0, 0})andqueue.add({0, 1})).
- Create a queue to store the nodes along with the color of the last edge used to reach them. Initialize the queue with the starting node
-
Perform BFS:
- While the queue is not empty:
- Dequeue the first element from the queue, which gives the current node and the color of the last edge used to reach it.
- For each neighbor of the current node in the graph of the opposite color:
- If the neighbor has not been visited via the current path (i.e.,
res[1 - color][neighbor] == Integer.MAX_VALUE), update the shortest path length to this neighbor and add it to the queue.
- If the neighbor has not been visited via the current path (i.e.,
- While the queue is not empty:
-
Generate Answer:
- For each node, the shortest path is the minimum value between the paths found via red and blue edges.
- If no valid path exists, set the distance to
-1.
Algorithm Walkthrough
Example Input
- n = 4
- redEdges = [[0, 1], [1, 2], [2, 3]]
- blueEdges = [[0, 2], [2, 1], [1, 3]]
-
Initialize Data Structures:
graph[0](red edges):[[], [], [], []]graph[1](blue edges):[[], [], [], []]res:[[0, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE], [0, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE]]queue:[{0, 0}, {0, 1}](node, color)
-
Build Graph:
- For red edges:
graph[0][0].add(1)->graph[0]:[[1], [], [], []]graph[0][1].add(2)->graph[0]:[[1], [2], [], []]graph[0][2].add(3)->graph[0]:[[1], [2], [3], []]
- For blue edges:
graph[1][0].add(2)->graph[1]:[[2], [], [], []]graph[1][2].add(1)->graph[1]:[[2], [], [1], []]graph[1][1].add(3)->graph[1]:[[2], [3], [1], []]
- For red edges:
-
Initialize BFS Queue:
- Queue starts as
[{0, 0}, {0, 1}].
- Queue starts as
-
Perform BFS:
- Dequeue
{0, 0}(node0with red edge):- Check blue neighbors of
0:graph[1][0]:[2]res[1][2]isInteger.MAX_VALUE:- Update
res[1][2] = res[0][0] + 1 = 1 - Enqueue
{2, 1}
- Update
- Check blue neighbors of
- Dequeue
{0, 1}(node0with blue edge):- Check red neighbors of
0:graph[0][0]:[1]res[0][1]isInteger.MAX_VALUE:- Update
res[0][1] = res[1][0] + 1 = 1 - Enqueue
{1, 0}
- Update
- Check red neighbors of
- Dequeue
{2, 1}(node2with blue edge):- Check red neighbors of
2:graph[0][2]:[3]res[0][3]isInteger.MAX_VALUE:- Update
res[0][3] = res[1][2] + 1 = 2 - Enqueue
{3, 0}
- Update
- Check red neighbors of
- Dequeue
{1, 0}(node1with red edge):- Check blue neighbors of
1:graph[1][1]:[3]res[1][3]isInteger.MAX_VALUE:- Update
res[1][3] = res[0][1] + 1 = 2 - Enqueue
{3, 1}
- Update
- Check blue neighbors of
- Dequeue
{3, 0}(node3with red edge):- No unvisited blue neighbors.
- Dequeue
{3, 1}(node3with blue edge):- No unvisited red neighbors.
- Dequeue
-
Generate Answer:
- For each node
i, the length of the shortest path is the minimum ofres[0][i]andres[1][i]:answer[0] = min(res[0][0], res[1][0]) = 0answer[1] = min(res[0][1], res[1][1]) = 1answer[2] = min(res[0][2], res[1][2]) = 1answer[3] = min(res[0][3], res[1][3]) = 2
- If no valid path exists, set the distance to
-1.
- For each node
Code
Complexity Analysis
Time complexity
The time complexity of the algorithm is O(V + E), where (V) is the number of vertices (nodes) and (E) is the number of edges. This is because the BFS traversal explores each vertex and edge once.
Space Complexity
The space complexity is also O(V + E), due to the space needed for the graph representation and the BFS queue.
On this page
Problem Statement
Examples
Solution
Step-by-Step Algorithm
Algorithm Walkthrough
Code
Complexity Analysis
Time complexity
Space Complexity