LeetCode in Kotlin

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

class Solution {
    private lateinit var adjList: MutableList<MutableList<Int>>
    private lateinit var result: MutableList<MutableList<Int>>

    fun getAncestors(n: Int, edges: Array<IntArray>): List<MutableList<Int>> {
        adjList = ArrayList()
        result = ArrayList()
        for (i in 0 until n) {
            adjList.add(ArrayList())
            result.add(ArrayList())
        }
        for (edge in edges) {
            val start = edge[0]
            val end = edge[1]
            adjList[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 (i in 0 until n) {
            val visited = BooleanArray(n)
            val childList: List<Int> = adjList[i]
            for (child in childList) {
                if (!visited[child]) {
                    dfs(i, child, visited)
                }
            }
        }
        return result
    }

    private fun dfs(root: Int, node: Int, visited: BooleanArray) {
        if (visited[node]) {
            return
        }
        visited[node] = true
        result[node].add(root)
        val childList: List<Int> = adjList[node]
        for (child in childList) {
            if (!visited[child]) {
                dfs(root, child, visited)
            }
        }
    }
}