Degree
In-degree and out-degree - how many edges point into and out of a node - are enough to answer a surprising range of graph questions without ever building an adjacency list or traversing an edge. Counting those two arrays over the raw edge list is the whole trick.
The definitions, the source/sink signal table, the handshake lemma and the self-check it gives you are on Graph Anatomy. This page is the practice set.
Sink & Source Identification
Find the one node whose degree hits an exact target - 0 for a plain source/sink, or n - 1 for a node everyone else points at.
997. Find the Town Judge
The town judge is defined by two conditions: everyone else trusts the judge (in-degree n - 1) and the judge trusts nobody (out-degree 0). Count both degrees for every person from the trust pairs, then scan people 1..n for the one node satisfying both. Iterating over range(1, n + 1) - rather than only the nodes that appear in trust - handles the single-person case (n = 1, empty trust) for free: node 1 has in-degree 0 == n - 1 and out-degree 0.
The magic number is n - 1, a fixed value from the input - not something derived from the trust data (like the number of trust pairs), which is a common trap.
- Time
- O(n + E)
- One pass over the
Etrust pairs to build the degree arrays -O(E). - One pass over the
npeople to find the judge -O(n). - Space
- O(n)
in_degreeandout_degreeare each sizen + 1-O(n).
1436. Destination City
1436Destination City
The destination city is the one path never leaves from - it has out-degree 0. Walk every [a, b] pair, bumping a's out-degree and making sure b is registered with an out-degree of at least 0 (via .get(b, 0)). The one city whose out-degree is 0 is the destination.
- Time
- O(2n)
n= number of paths. Thefor a, b in pathsloop buildsout_degreein one pass -O(n).- The
for i, j in out_degree.items()loop scans the map for the city with out-degree0- anotherO(n)pass. Two separate passes give2n. - Space
- O(n)
out_degreeholds at mostn + 1cities, one per distinct city seen across allnpaths.
1557. Minimum Number of Vertices to Reach All Nodes
The graph is a DAG, so any node with in-degree > 0 is reachable from whichever node has an edge into it - and transitively from that node's ancestors. Following those edges back far enough always bottoms out at a node with in-degree 0, since a DAG has no cycle to loop back into. That makes every in-degree-0 node unreachable from anywhere else, so all of them must be included, and reachable from any starting set, so none of the other nodes need to be.
Count in-degree by scanning edges once, then collect every index whose in-degree is still 0.
- Time
- O(n + E)
- One pass over the
Eedges to buildin_degree, one pass over thennodes to collect the roots. - Space
- O(n)
- The
in_degreearray and theresultlist are both sized ton.
Greedy Elimination
Both model "the one node everyone points at, that points at no one" - but instead of counting degrees, they walk the nodes once with a running candidate, discarding it whenever the current node disproves it. One survivor is left after a single pass.
2923. Find Champion I
2923Find Champion I
grid[i][j] == 1 is a directed edge i -> j meaning team i beats team j. A champion beats every other team, so its win count - in_degree[i] in the code, one increment per grid[i][j] == 1 - must equal n - 1. Scan every ordered pair to build the count array, then scan it for the team with n - 1 wins.
- Time
- O(n + n^2)
- The nested loop over
iandjchecks every ordered pair to buildin_degree-O(n^2). - A second, separate pass over
in_degreelooks for the entry equal ton - 1-O(n). - Space
- O(n)
in_degreeis a count array of sizen.
277. Find the Celebrity
Model knows(a, b) as a directed edge a -> b. The celebrity is the one node everyone else points to (in-degree n - 1) that points to no one (out-degree 0) - exactly the town-judge condition, except the trust pairs are replaced by n * (n - 1) calls to the knows API. Probe every ordered pair (i, j) with i != j, accumulate both degree arrays, then scan for the node satisfying both conditions.
This is correct but wasteful: it makes the full O(n^2) set of knows calls even though the answer can be found with far fewer.
- Time
- O(n + n^2)
- The nested loop over every ordered pair
(i, j)callsknowsO(n^2)times to fill both degree arrays, then a separateO(n)scan looks for the node satisfying both degree conditions -n + n^2. - Space
- O(2n)
in_degreesandout_degreesare each a separate array of sizen-2n.
Degree Arithmetic
Combine degrees across multiple nodes, correcting for edges shared between them.
1615. Maximal Network Rank
The rank of a pair of cities (a, b) is the number of roads touching either one, counting a direct road between them only once. That's degree[a] + degree[b], minus 1 if a and b are directly connected (otherwise their shared road would be double-counted).
Build degree and an adjacency set (adj_list) from roads in one pass, then try every ordered pair (a, b) and take the best degree[a] + degree[b] - (b in adj_list[a]) - Python's bool subtracts as 0 or 1 directly.
- Time
- O(E + n^2)
- Building
degreeandadj_listisO(E). - Checking every ordered pair
(a, b)isO(n^2), each with anO(1)set lookup. - Space
- O(n + E)
- The
degreearray isO(n);adj_liststores each edge twice,O(E).