Jc-alt logo
jc
data structures and algorithms

LeetCode: Graphs I Undirected Degree

LeetCode: Graphs I Undirected Degree
7 min read
#data structures and algorithms

Undirected Degree Intro

LeetCode problems with graph based solutions, specifically dealing with the nodes in and out degrees

1791. Find Center of Star Graph ::1:: - Easy

Topics: Degree Counting, Graph Theory, Edge List

Intro

There is an undirected star graph consisting of n nodes labeled from 1 to n. A star graph is a graph where there is one center node and exactly n - 1 edges that connect the center node with every other node. You are given a 2D integer array edges where each edges[i] = [ui, vi] indicates that there is an edge between the nodes ui and vi. Return the center of the given star graph.

Example InputOutput
edges = [[1,2],[2,3],[4,2]]2
edges = [[1,2],[5,1],[1,3],[1,4]]1

Constraints:

3 ≤ n ≤ 10^5

edges.length == n-1

edges[i].length == 2

1 ≤ ui, vi ≤ n

ui != vi

The given edges represent a valid star graph

Abstraction

Find the node that appears in every edge (the one shared by both the first and second edge). Given an Edge List representation of an undirected star graph. This is a degree-counting problem, not a traversal problem, the center is simply the node with degree n-1.

Space & Time Complexity

SolutionTime ComplexitySpace ComplexityTime RemarkSpace Remark
BugError

Brute Force:

AspectTime ComplexitySpace ComplexityTime RemarksSpace Remarks

Find the Bug:

Solution 1: [Degree Counting] Shared Node In First Two Edges - Graph/Degree Counting

    def findCenter(self, edges: List[List[int]]) -> int:
        
        # Note:
        # Finding the center of a star graph
        # using an Edge List

        # Edge List:
        # edges = [
        #     [1, 2],
        #     [2, 3],
        #     [4, 2],
        # ]

        # In a star graph, every single edge touches the center node,
        # since the center connects to every other node directly. That
        # means the center is guaranteed to appear in EVERY edge, so we
        # never need to scan the whole edge list or count degrees at all,
        # we only need to look at the first two edges.

        # The center is whichever node is shared between edge 0 and
        # edge 1. Any node that appears in both must be the center,
        # since a non-center (leaf) node only ever appears in exactly
        # one edge (its single connection to the center).

        # Grab First Two Edges:
        # tc: O(1)
        u1, v1 = edges[0]
        u2, v2 = edges[1]

        # Shared Node Check:
        # if either node from edge 0 also appears in edge 1, it's the center
        if u1 == u2 or u1 == v2:
            return u1

        # overall: tc O(1)
        # overall: sc O(1)
        return v1
AspectTime ComplexitySpace ComplexityTime RemarksSpace Remarks

What is a In Out Degree?

Has to do with the celebrity vs person graph problem. A celebrity may have many in degrees, but few out degrees. While a person may have many out degrees, but few in degrees.

1615. Maximal Network Rank ::1:: - Medium

Topics: Degree Counting, Graph Theory, Edge List

Intro

There is an infrastructure of n cities with some number of roads connecting these cities. Each roads[i] = [ai, bi] indicates that there is a bidirectional road between cities ai and bi. The network rank of two different cities is defined as the total number of directly connected roads to either city. If a road is directly connected to both cities, it is only counted once. The maximal network rank of the infrastructure is the maximum network rank of all pairs of different cities. Given the integer n and the array roads, return the maximal network rank of the entire infrastructure.

Example InputOutput
n = 4, roads = [[0,1],[0,3],[1,2],[1,3]]4
n = 5, roads = [[0,1],[0,3],[1,2],[1,3],[2,3],[2,4]]5
n = 8, roads = [[0,1],[1,2],[2,3],[2,4],[5,6],[5,7]]5

Constraints:

2 ≤ n ≤ 100

0 ≤ roads.length ≤ n * (n-1) / 2

roads[i].length == 2

0 ≤ ai, bi ≤ n-1

ai != bi

Each pair of cities has at most one road connecting them.

Abstraction

For every pair of cities, compute degree(a) + degree(b) - (1 if directly connected, else 0), and return the maximum value found. Given an Edge List representation of a graph. This is a degree-counting problem, not a connectivity/traversal problem, so DFS/BFS/Union-Find don't apply.

Space & Time Complexity

SolutionTime ComplexitySpace ComplexityTime RemarkSpace Remark
BugError

Brute Force:

AspectTime ComplexitySpace ComplexityTime RemarksSpace Remarks

Find the Bug:

Solution 1: [Degree Counting] Precomputed Degree + Adjacency Set Pairwise Scan - Graph/Degree Counting

    def maximalNetworkRank(self, n: int, roads: List[List[int]]) -> int:
        
        # Note:
        # Maximal Network Rank is a degree-counting problem, not a
        # connectivity problem, so DFS/BFS/Union-Find don't apply here.
        # We never need to traverse beyond a node's immediate neighbors.

        # Edge List:
        # roads = [
        #     [0, 1],
        #     [0, 2],
        #     [1, 2],
        # ]

        # The network rank of two cities is the total number of roads
        # touching either city, counted once each even if both cities
        # share a direct road between them.

        # Precompute Degree Array:
        # degree[i] = number of roads touching city i
        # tc: O(E)
        # sc: O(V)
        degree = [0] * n
        for u, v in roads:
            degree[u] += 1
            degree[v] += 1

        # Precompute Adjacency Set:
        # for O(1) "are these two cities directly connected" checks
        # sc: O(E)
        connected = set()
        for u, v in roads:
            connected.add((u, v))
            connected.add((v, u))

        # Check All Pairs:
        # tc: O(V^2)
        maxRank = 0

        for i in range(n):
            for j in range(i + 1, n):

                # Network Rank Formula:
                # sum of both degrees, minus 1 if directly connected
                # (a shared road would otherwise be double counted)
                rank = degree[i] + degree[j]

                if (i, j) in connected:
                    rank -= 1

                maxRank = max(maxRank, rank)

        # overall: tc O(V^2 + E), V^2 for the pairwise scan (dominates
        #   for dense graphs), E for building degree/adjacency structures
        # overall: sc O(V + E), for the degree array and adjacency set
        return maxRank
AspectTime ComplexitySpace ComplexityTime RemarksSpace Remarks