Graphs Overview
Introduction to Graphs and adapting DFS for cycles.
What is a Graph?
A Graph is a non-linear data structure consisting of vertices (nodes) and edges (lines connecting nodes). Unlike specific tree structures, graphs have no strict hierarchy-any node can be connected to any other node.
Key Terminology
- Vertex (Node): The fundamental unit (e.g., a City, User, Webpage).
- Edge: The connection between two vertices (e.g., Road, Follow, Hyperlink).
- Degree: The number of edges connected to a vertex. In directed graphs, this splits into in-degree (incoming) and out-degree (outgoing).
- Path: A sequence of edges connecting a sequence of vertices.
Real-World Examples
- Social Networks: Users are nodes, friendships are edges.
- Google Maps: Intersections are nodes, roads are edges.
- The Internet: Webpages are nodes, hyperlinks are edges.
Types of Graphs
Key distinctions you must know:
Directed (DiGraph): Edges have a direction (A → B). Moving from A to B is allowed, but B to A is not (unless a separate edge exists). e.g., Twitter followers.
Undirected: Edges are bidirectional (A - B). e.g., Facebook friends.
Weighted: Edges have values (weights) assigned to them. e.g., Flight costs between cities.
Cyclic vs Acyclic: A cyclic graph contains at least one path that starts and ends at the same node using different edges.
Connected vs Disconnected: In a connected graph, there is a path between every pair of vertices. Disconnected graphs have isolated sub-graphs (islands).
Graph Representations
How do we store a graph in code? There are two primary ways:
Adjacency Matrix: A 2D array where
grid[i][j] = 1if there is an edge fromitoj.- Pros: O(1) edge lookup.
- Cons: O(V²) space, even if the graph is sparse.
Adjacency List (Most Common): A Map or Array of Lists where each key is a node and the value is a list of its neighbors.
- Pros: O(V + E) space. Efficient for sparse graphs.
- Cons: O(Degree) to check if a specific edge exists.
We will focus primarily on the Adjacency List as it is the most common representation in technical interviews.
DFS on Graphs: The 'Visited' Set
DFS on a graph works just like on a tree: we explore as deep as possible before backtracking. However, there is one critical difference:
Cycles and Revisited Nodes
In a tree, we always move down from parent to child, guaranteeing we never visit the same node twice. In a graph, edges can point anywhere. A node can point back to its ancestor (cycle) or two nodes can point to the same neighbor.
Without tracking where we've been, our DFS would recurse infinitely in a cycle (A → B → A → ...).
The Solution: The visited Set
We strictly enforce a rule: "Never process a node more than once."
We maintain a HashSet (or boolean array) called visited.
- Before traversing to a neighbor, check if it's in
visited. - If yes, skip it.
- If no, mark it as visited and recurse.
Handling Disconnected Graphs
A single DFS starting from node 0 might not reach all nodes if the graph is disconnected (has "islands").
To handle this, we wrap our DFS in a loop over all nodes:
for i in range(num_nodes):
if i not in visited:
dfs(i)
This ensures every Connected Component is visited.
DFS Graph Visualization
Graph Structure. Starting DFS from Node 0.
See the Logic in Motion
Stop memorizing code. Unlock the full interactive visualizer to master the logic step-by-step.- What is a Graph?
- Types of Graphs
- Graph Representations
- DFS on Graphs: The 'Visited' Set
- Handling Disconnected Graphs
- DFS Graph Visualization
- Edge Cases & Common Mistakes
- Graph DFS Template
- Complexity Analysis
- Summary
Stop Guessing, Start Mastering.
Build the FAANG intuition. Master this pattern with optimized implementations, visual dry runs, and our curated collection of high-yield problems.
