LeetCode-in-Java

2192. All Ancestors of a Node in a Directed Acyclic Graph

Medium

You are given a positive integer n representing the number of nodes of a Directed Acyclic Graph (DAG). The nodes are numbered from 0 to n - 1 (inclusive).

You are also given a 2D integer array edges, where edges[i] = [fromi, toi] denotes that there is a unidirectional edge from fromi to toi in the graph.

Return a list answer, where answer[i] is the list of ancestors of the ith node, sorted in ascending order.

A node u is an ancestor of another node v if u can reach v via a set of edges.

Example 1:

Input: n = 8, edgeList = [[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]]

Output: [[],[],[],[0,1],[0,2],[0,1,3],[0,1,2,3,4],[0,1,2,3]]

Explanation:

The above diagram represents the input graph.

Example 2:

Input: n = 5, edgeList = [[0,1],[0,2],[0,3],[0,4],[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]

Output: [[],[0],[0,1],[0,1,2],[0,1,2,3]]

Explanation:

The above diagram represents the input graph.

Constraints:

Solution

import java.util.ArrayList;
import java.util.List;

public class Solution {
    private List<List<Integer>> adjList;
    private List<List<Integer>> result;

    public List<List<Integer>> getAncestors(int n, int[][] edges) {
        this.adjList = new ArrayList<>();
        this.result = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            adjList.add(new ArrayList<>());
            result.add(new ArrayList<>());
        }
        for (int[] edge : edges) {
            int start = edge[0];
            int end = edge[1];
            adjList.get(start).add(end);
        }
        //  DFS for each node from 0 --> n , and add that node as root/parent into each reachable
        // node and their child
        //  Use visited[] to identify if any of the child or their childs are already visited for
        // that perticular root/parent,
        //  so will not add the root to avoid duplicacy and call reduction .
        for (int i = 0; i < n; i++) {
            boolean[] visited = new boolean[n];
            List<Integer> childList = adjList.get(i);
            for (Integer child : childList) {
                if (!visited[child]) {
                    dfs(i, child, visited);
                }
            }
        }
        return result;
    }

    private void dfs(int root, int node, boolean[] visited) {
        if (visited[node]) {
            return;
        }
        visited[node] = true;
        result.get(node).add(root);
        List<Integer> childList = adjList.get(node);
        for (Integer child : childList) {
            if (!visited[child]) {
                dfs(root, child, visited);
            }
        }
    }
}