↓Skip to main content
  1. LeetCode/

LeetCode 2858: Minimum Edge Reversals So Every Node Is Reachable

·2 mins· ·
LeetCode Hard Dynamic-Programming Depth-First-Search Breadth-First-Search Graph
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: hard First Attempt: 2026-10-31

  • Submissions: Accepted ×2

Approach
#

The edges are directed, but without directions they form a tree. Reaching every node from i means every edge must point away from i. So ans[i] is the number of edges pointing toward the root when i is the root.

Computing that per node is O(n^2). Use rerooting DP (as in LC 834):

  1. BFS with root 0 and count the edges that point from a child to its parent. That is ans[0].
  2. Moving the root from p to its child v only changes the p–v edge:
    • Originally p → v (pointing down): with v as the root it points up, one more reversal, ans[v] = ans[p] + 1.
    • Originally v → p (pointing up): it needed reversing for root p but not for root v, ans[v] = ans[p] - 1.

A set of the original directed edges tells whether an edge points down.

My Attempts
#

Both submissions passed on the first try (once on 10-31, and a rewrite that afternoon).

Solution
#

class Solution:
    def minEdgeReversals(self, n: int, edges: List[List[int]]) -> List[int]:
        graph = defaultdict(list)
        for u, v in edges:
            graph[u].append(v)
            graph[v].append(u)
        forward = {(u, v) for u, v in edges}

        parent = [-1] * n
        seen = [False] * n
        seen[0] = True
        order = []
        queue = deque([0])
        while queue:
            node = queue.popleft()
            order.append(node)
            for nei in graph[node]:
                if not seen[nei]:
                    seen[nei] = True
                    parent[nei] = node
                    queue.append(nei)

        ans = [0] * n
        ans[0] = sum(1 for v in order[1:] if (parent[v], v) not in forward)
        for v in order[1:]:
            p = parent[v]
            ans[v] = ans[p] + (1 if (p, v) in forward else -1)
        return ans

Complexity
#

Time O(n), space O(n).

Mistakes to Avoid
#

  • Reroot top-down in BFS order so ans[p] is ready before its children.
  • Build the graph in both directions, or nodes reachable only against an edge’s direction are never visited.

Interview Explanation
#

Without directions it is a tree, and reaching all nodes from i means every edge must point away from i, so the answer is the number of edges pointing up when i is the root. I count that for root 0, then reroot: moving the root from p to v only changes that edge, adding one if it was p → v and subtracting one if it was v → p. Time O(n).

Related

LeetCode 834: Sum of Distances in Tree
·3 mins
LeetCode Hard Dynamic-Programming Tree Depth-First-Search Graph Dp-on-Trees
LeetCode 834 note: rerooting DP: compute subtree sizes and ans[0] with root 0, then push ans[child] = ans[parent] - size + (n - size) to every node
LeetCode 968: Binary Tree Cameras
·3 mins
LeetCode Hard Dynamic-Programming Tree Depth-First-Search Binary-Tree Dp-on-Trees
LeetCode 968 note: post-order greedy with three states per node: has a camera, covered, not covered; place a camera only when a child is uncovered, and add one if the root is left uncovered
LeetCode 297: Serialize and Deserialize Binary Tree
·2 mins
LeetCode Hard String Tree Depth-First-Search Breadth-First-Search Design Binary-Tree
LeetCode 297 note: pre-order with null markers identifies the tree uniquely; deserialize by consuming tokens from an iterator
LeetCode 124: Binary Tree Maximum Path Sum
·2 mins
LeetCode Hard Dynamic-Programming Tree Depth-First-Search Binary-Tree Dp-on-Trees
LeetCode 124 note: DFS returns the best downward chain and updates the answer with left chain + node + right chain at every node; drop negative chains
LeetCode 2973: Find Number of Coins to Place in Tree Nodes
·3 mins
LeetCode Hard Dynamic-Programming Tree-Dp Depth-First-Search Sorting Heap Tree
LeetCode 2973 note: the max product of three is either the three largest or the two smallest times the largest, so each subtree returns only its 2 smallest and 3 largest values, merged in post-order
LeetCode 1373: Maximum Sum BST in Binary Tree
·2 mins
LeetCode Hard Dynamic-Programming Tree-Dp Binary-Search-Tree Depth-First-Search Tree
LeetCode 1373 note: a post-order traversal returns (sum, min, max, is_bst); a node roots a BST when the left max < its value < the right min