Skip to content

Commit c06de13

Browse files
committed
Graphj
1 parent 69b01c8 commit c06de13

2 files changed

Lines changed: 92 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# https://leetcode.com/problems/all-paths-from-source-lead-to-destination/description/
2+
3+
'''
4+
Given the edges of a directed graph where edges[i] = [ai, bi] indicates there is an edge between nodes ai and bi, and two nodes source and destination of this graph, determine whether or not all paths starting from source eventually, end at destination, that is:
5+
6+
At least one path exists from the source node to the destination node
7+
If a path exists from the source node to a node with no outgoing edges, then that node is equal to destination.
8+
The number of possible paths from source to destination is a finite number.
9+
Return true if and only if all roads from source lead to destination.
10+
11+
12+
13+
Example 1:
14+
15+
16+
Input: n = 3, edges = [[0,1],[0,2]], source = 0, destination = 2
17+
Output: false
18+
Explanation: It is possible to reach and get stuck on both node 1 and node 2.
19+
Example 2:
20+
21+
22+
Input: n = 4, edges = [[0,1],[0,3],[1,2],[2,1]], source = 0, destination = 3
23+
Output: false
24+
Explanation: We have two possibilities: to end at node 3, or to loop over node 1 and node 2 indefinitely.
25+
Example 3:
26+
27+
28+
Input: n = 4, edges = [[0,1],[0,2],[1,3],[2,3]], source = 0, destination = 3
29+
Output: true
30+
31+
32+
Constraints:
33+
34+
1 <= n <= 104
35+
0 <= edges.length <= 104
36+
edges.length == 2
37+
0 <= ai, bi <= n - 1
38+
0 <= source <= n - 1
39+
0 <= destination <= n - 1
40+
The given graph may have self-loops and parallel edges.
41+
'''
42+
43+
class Solution:
44+
BLACK=2
45+
GRAY=1
46+
def recursive(self,source,destination,states):
47+
if states[source]!=0:
48+
return states[source]==Solution.BLACK
49+
if len(self.adj_list[source])==0:
50+
return source==destination
51+
states[source]=Solution.GRAY
52+
for next_node in self.adj_list[source]:
53+
if not self.recursive(next_node,destination,states):
54+
return False
55+
states[source]=Solution.BLACK
56+
return True
57+
58+
def leadsToDestination(self, n: int, edges: List[List[int]], source: int, destination: int) -> bool:
59+
self.adj_list=defaultdict(list)
60+
states=[0]*n
61+
self.cnt=0
62+
for i in range(len(edges)):
63+
self.adj_list[edges[i][0]].append(edges[i][1])
64+
return self.recursive(source,destination,states)
65+
66+
'''
67+
Complexity Analysis
68+
69+
Time Complexity: Typically for an entire DFS over an input graph, it takes O(V+E) where V represents the number of vertices in the graph and likewise,
70+
E represents the number of edges in the graph. In the worst case E can be O(V^2) in case each vertex is connected to every other vertex in the graph.
71+
However even in the worst case, we will end up discovering a cycle very early on and prune the recursion tree. If we were to traverse the entire graph, then the complexity would be O(V 2) as the O(E) part would dominate.
72+
However, due to pruning and backtracking in case of cycle detection, we end up with an overall time complexity of O(V).
73+
74+
Space Complexity: O(V+E) where O(E) is occupied by the adjacency list and O(V) is occupied by the recursion stack and the color states.
75+
'''

Graph/Material.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Static Connectivity
2+
3+
If the entire graph is provided upfront in the problem (for example, this problem directly provides the grid through a 2D array grid), and we are then asked queries about connectivity (such as whether there exists a path from the start to the end), this is referred to as static connectivity.
4+
5+
The opposite concept is dynamic connectivity, where graph updates and connectivity queries are interleaved. In other words, after a connectivity query, the graph may still be modified. For example, if this problem included multiple queries where each query modifies a position in grid and then checks whether a valid path exists, with modifications persisting across queries, then it would be considered a dynamic connectivity problem.
6+
7+
For static connectivity problems, depth-first search, breadth-first search, and union-find can generally be used. These methods are conceptually similar, and the main challenge lies in constructing the graph, specifically determining which pairs of nodes should be connected.
8+
9+
Once the graph is constructed, we can easily determine whether two nodes are connected using any of these approaches.
10+
11+
In this solution, we focus on the Union-Find method. We treat each cell as a node in the graph, and define edges based on direct reachability between adjacent cells. Here, "direct reachability" means that a cell can move directly to one of its neighboring cells (up, down, left, or right).
12+
13+
For example, a cell with value 1 represents a street connecting the left and right cells, while a cell with value 3 connects the left and bottom cells. Therefore, if a cell with value 1 is to the left of a cell with value 3, these two cells are directly reachable. We can use Union-Find to maintain these relationships.
14+
15+
However, Union-Find operates on one-dimensional indices, while our grid is two-dimensional. Therefore, we map each cell (x,y) to a unique integer ID using the formula:
16+
id=x×n+y
17+
where n is the number of columns. This mapping ensures that each cell corresponds to a unique node in the Union-Find structure.

0 commit comments

Comments
 (0)