4 of 7
Write a function count_indegrees(num_nodes, edges) that returns a dictionary mapping each node to its in-degree β how many edges point to it.
print(count_indegrees(4, [[0,1], [0,2], [1,3], [2,3]])) # Output: {0: 0, 1: 1, 2: 1, 3: 2} # Node 3 has 2 edges pointing to it (from 1 and 2) print(count_indegrees(3, [[0,1], [1,2], [2,0]])) # Output: {0: 1, 1: 1, 2: 1} # Each node has exactly one incoming edge print(count_indegrees(3, [])) # Output: {0: 0, 1: 0, 2: 0} # No edges β all in-degrees are 0 print(count_indegrees(4, [[0,3], [1,3], [2,3]])) # Output: {0: 0, 1: 0, 2: 0, 3: 3} # Node 3 is a "collector" β three nodes point to it
| Complexity | |
|---|---|
| Time | O(V + E) |
| Space | O(V) |
Where V is the number of nodes and E is the number of edges.
[a, b], increment the in-degree of b (the destination)Key insight: Only the destination matters for in-degree. Edge [a, b] adds 1 to b's in-degree, not a's.
def count_indegrees(num_nodes, edges): # Your code here pass # Test your function: print(count_indegrees(4, [[0,1], [0,2], [1,3], [2,3]])) # Output: {0: 0, 1: 1, 2: 1, 3: 2} print(count_indegrees(3, [[0,1], [1,2], [2,0]])) # Output: {0: 1, 1: 1, 2: 1} print(count_indegrees(3, [])) # Output: {0: 0, 1: 0, 2: 0} print(count_indegrees(4, [[0,3], [1,3], [2,3]])) # Output: {0: 0, 1: 0, 2: 0, 3: 3} print(count_indegrees(5, [[0,1], [0,2], [1,3], [2,3], [3,4]])) # Output: {0: 0, 1: 1, 2: 1, 3: 2, 4: 1}
Start every node at 0:
indegree = {i: 0 for i in range(num_nodes)}
This ensures every node has an entry, even nodes that no edge points to.
For edge [a, b], the arrow points from a to b. So b gains an incoming edge:
indegree[b] += 1
Don't touch a β it's the source, not the destination.
def count_indegrees(num_nodes, edges): indegree = {i: 0 for i in range(num_nodes)} for a, b in edges: indegree[b] += 1 return indegree
Why does this matter? In-degrees are the key to Kahn's algorithm for topological sort (coming up soon). Nodes with in-degree 0 have no prerequisites β they can go first.