Graph Modeling
Lesson 33Intermediate54 minAssessment-backed

Graph Modeling

Represent relationships, dependencies, networks, routes, permissions, and reachability with adjacency structures.

What you will be able to do

Model entities as vertices and relationships as edges.
Choose directed, undirected, weighted, or unweighted graph representation.
Build adjacency lists from edge lists in Java, Python, and JavaScript.
Explain when a tree assumption breaks and a graph needs visited tracking.
Connect graph modeling to social networks, permissions, dependencies, routes, and recommendations.

A graph is the structure for relationships. Users follow users, services depend on services, cities connect by routes, permissions inherit through groups, and recommendations move through shared behavior. The algorithm only becomes clear after the model is precise.

Vertices and Edges

A vertex is an entity. An edge is a relationship. Directed edges have a source and destination. Undirected edges are symmetric. Weighted edges carry cost such as distance, latency, risk, or price.

Directed undirected and weighted graph examples
Graph modeling starts by deciding what each edge means.

Scenario: Permission Inheritance

A user belongs to teams; teams inherit permissions from parent teams; projects grant access to teams. This is no longer a simple tree if a team can have multiple parents. A graph model plus visited tracking prevents repeated work and infinite loops.

Product relationGraph choiceWhy
Follow graphDirectedA follows B does not imply B follows A.
Road mapWeighted graphDistance or time matters.
FriendshipUndirectedRelationship is symmetric.
Build dependenciesDirected acyclic graphDependencies point from work to prerequisite.
Adjacency list representation
Adjacency lists are the default representation for sparse production graphs.

Same Pattern in Java, Python, and JavaScript

Most graph code starts by transforming an edge list into an adjacency list so traversal can quickly find neighbors.

import java.util.*;

class GraphBuilder {
    static Map<String, List<String>> buildDirected(List<String[]> edges) {
        Map<String, List<String>> graph = new HashMap<>();
        for (String[] edge : edges) {
            graph.computeIfAbsent(edge[0], key -> new ArrayList<>()).add(edge[1]);
            graph.computeIfAbsent(edge[1], key -> new ArrayList<>()); // Keep destination visible.
        }
        return graph;
    }
}

Assessment trap

Do not force graph data into tree logic. Multiple parents, cycles, and cross-links require visited tracking and a clear edge meaning.

Interview signalFrequently Asked Interview Questions

These are canonical interview patterns for this topic, phrased as concrete problem statements. They avoid vague theory questions and prepare you for the exact reasoning interviewers expect: invariant, edge cases, complexity, and trade-off.

  • Given directed edges, build an adjacency list that preserves terminal nodes.
  • Given a directed graph, start, and target, return whether a path exists.
  • Given n nodes and undirected edges, return whether the graph is a valid tree.

Production practiceCompany-Style Practice Examples

These are not claimed as exact company-specific questions. They are the interview patterns repeatedly used by product companies to test whether you can move from brute force to a defensible implementation.

ExampleBrute-force approachStronger solutionProduction notes
Permission inheritanceTreat teams as a strict tree.Model users, teams, projects, and grants as a directed graph.Multiple parents and cycles require visited tracking.
Service dependenciesStore only a flat service list.Build a directed dependency graph from caller to callee or service to prerequisite.Direction must match the question being answered.
Friend recommendationsScan every user pair.Model friendships/interactions as graph edges and traverse nearby neighborhoods.Control privacy boundaries and ranking signals.

Solved modelInterview Question Solutions

Question 1: Build Adjacency List

Given directed edges, build an adjacency list that preserves terminal nodes. Use a map from source node to outgoing neighbors. Add destination nodes even when they have no outgoing edges so traversals and counts remain correct.

import java.util.*;

class GraphBuilder {
    static Map<String, List<String>> buildDirected(List<String[]> edges) {
        Map<String, List<String>> graph = new HashMap<>();
        for (String[] edge : edges) {
            graph.computeIfAbsent(edge[0], key -> new ArrayList<>()).add(edge[1]);
            graph.computeIfAbsent(edge[1], key -> new ArrayList<>()); // Keep destination visible.
        }
        return graph;
    }
}

Question 2: Path Exists in Directed Graph

Given a directed graph, start, and target, return whether a path exists. Use graph traversal with visited tracking. DFS is concise for reachability; BFS is also valid when distance is needed.

import java.util.*;
class PathExists { static boolean exists(Map<String,List<String>> g, String s, String t) { Set<String> seen = new HashSet<>(); return dfs(g, s, t, seen); } static boolean dfs(Map<String,List<String>> g, String node, String target, Set<String> seen) { if (node.equals(target)) return true; if (!seen.add(node)) return false; for (String next : g.getOrDefault(node, List.of())) if (dfs(g, next, target, seen)) return true; return false; } }

Question 3: Graph Valid Tree

Given n nodes and undirected edges, return whether the graph is a valid tree. A valid tree has exactly n - 1 edges and is connected. Build an undirected graph, traverse from one node, and verify all nodes were reached.

import java.util.*;
class ValidTree { static boolean valid(int n, int[][] edges) { if (edges.length != n - 1) return false; List<List<Integer>> g = new ArrayList<>(); for (int i = 0; i < n; i++) g.add(new ArrayList<>()); for (int[] e : edges) { g.get(e[0]).add(e[1]); g.get(e[1]).add(e[0]); } Set<Integer> seen = new HashSet<>(); Deque<Integer> stack = new ArrayDeque<>(); stack.push(0); seen.add(0); while (!stack.isEmpty()) for (int next : g.get(stack.pop())) if (seen.add(next)) stack.push(next); return seen.size() == n; } }

Solved modelWorked Interview Answer

Build a directed adjacency list from relationship edges. The adjacency list keeps traversal cheap by storing each node's outgoing neighbors. Include nodes with no outgoing edges so isolated or terminal vertices are not lost.

import java.util.*;

class GraphBuilder {
    static Map<String, List<String>> buildDirected(List<String[]> edges) {
        Map<String, List<String>> graph = new HashMap<>();
        for (String[] edge : edges) {
            graph.computeIfAbsent(edge[0], key -> new ArrayList<>()).add(edge[1]);
            graph.computeIfAbsent(edge[1], key -> new ArrayList<>()); // Keep destination visible.
        }
        return graph;
    }
}

Hands-on drillTry It Yourself

Practice task

Model users, teams, and projects as a graph. Decide which edges are directed, which are weighted, and where cycles can appear.

Failure patternsCommon Mistakes to Avoid

  • Confusing vertex identity with display label.
  • Forgetting nodes with no outgoing edges.
  • Using tree traversal when nodes can have multiple parents.
  • Ignoring direction of edges.
  • Not defining what edge weight means.

Execution guardrailQuick-Start Checklist

  • Define vertices.
  • Define edge meaning.
  • Choose directed or undirected.
  • Choose weighted or unweighted.
  • Build adjacency list.
  • Add visited tracking before traversal.

Recall drillKnowledge Check

QuestionStrong answer
What is a vertex?An entity/node in the relationship model.
What is an adjacency list?A map from node to its neighbors.
Why keep isolated nodes?They may matter for counts, permissions, or no-dependency cases.

VocabularyKey Terms

TermMeaning
VertexA graph node/entity.
EdgeA relationship between vertices.
Directed graphEdges have source and destination.
Weighted graphEdges carry cost.
Adjacency listNeighbor list keyed by vertex.

Next practiceFurther Reading

  • Practice graph valid tree, clone graph, and route existence.
  • Compare adjacency lists with matrices.
  • Review graph modeling before BFS and DFS.