All Ancestors of a Node in a Directed Acyclic Graph
Problem
Intuition
It can be modelled as topological sort problem. Basically we need to find the ancestors of each node. And when traversing from one node to another
1 -> 3 -> 5
All the ancestors of 3 and 1 are also ancestors of 5. It is a basic traversal using Kahns algorithm, where we keep track of processed node
Code
class Solution {
public List<List<Integer>> getAncestors(int n, int[][] edges) {
// N -> Number of
// T.C :
// S.C : O(n)
List<List<Integer>> result = new ArrayList<>(); // Result container
List<TreeSet<Integer>> ancestors = new ArrayList<>(); // Ancestors for a given node
// Modelling the edges to adjacent map
Map<Integer, List<Integer>> graph = new HashMap<>();
// Init graph and ancestors
for(int i=0;i<n;i++) {
graph.put(i, new ArrayList());
ancestors.add(i, new TreeSet());
}
int[] indegree = new int[n]; // Keeps track of number of incoming nodes to current node
// Populating graph and indegree
for(int[] edge: edges) {
int source = edge[0];
int dest = edge[1];
graph.get(source).add(dest);
indegree[dest]++;
}
Deque<Integer> queue = new ArrayDeque<>();
// Add all the node which does not have ancestors to the queue for processing
for(int i=0;i<n;i++) {
if(indegree[i]==0){
queue.offer(i);
}
}
// Dont stop till you process all the node in the queue
while(!queue.isEmpty()) {
int parentNode = queue.poll();
// Explore the parent node childs
for(int childNode: graph.get(parentNode)) {
// Check if the parent node has any ancestors
if(!ancestors.get(parentNode).isEmpty()) {
// If so, add those ancestors to childNode
// Cz, as per def, ancestor means it can reach from any set of edges
ancestors.get(childNode).addAll(ancestors.get(parentNode));
}
// Add the parent node as ancestor to the child node
ancestors.get(childNode).add(parentNode);
// As we processed one prerequsite, decrement the indegree of childnode
indegree[childNode]--;
// If all the childnode prerequsites are done,
// add it to queue for processing
if(indegree[childNode] == 0) {
queue.offer(childNode);
}
}
}
// Convert the treeset to array list and add to the result
for(var ancestorPath: ancestors) {
result.add(new ArrayList(ancestorPath));
}
return result;
}
}
Last updated
Was this helpful?