力扣算法学习day43-2 --双周赛-T3
双周赛T3 - 5300-有向无环图中一个节点的所有祖先
题目
代码实现
class Solution {
// 方法一:拓扑排序 速度:177ms
// public List<List<Integer>> getAncestors(int n, int[][] edges) {
// List<List<Integer>> result = new ArrayList<>();
// List<Set<Integer>> quchong = new ArrayList<>();
// LinkedList<Integer> queue = new LinkedList<>();
// // 邻接矩阵
// int[][] am = new int[n][n];
// // 入度数组
// int[] inD = new int[n];
// // 1.填充邻接矩阵,和入度数组
// for(int i = 0;i < edges.length;i++){
// am[edges[i][0]][edges[i][1]] = 1;
// inD[edges[i][1]]++;
// }
// // 2.拓扑排序,首先将初始入度为0的节点放入队列中。顺带初始化quchong和result两个容器。
// for(int i = 0;i < inD.length;i++){
// if(inD[i] == 0){
// queue.offer(i);
// }
// result.add(new ArrayList<>());
// quchong.add(new TreeSet<>());
// }
// // 3.将重复弹出结点,记录为
// while(!queue.isEmpty()){
// int temp = queue.poll();
// Set<Integer> person = quchong.get(temp);
// for(int i = 0;i < am.length;i++){
// if(am[temp][i] != 1){
// continue;
// }
// Set<Integer> child = quchong.get(i);
// child.add(temp);
// child.addAll(person);
// inD[i]--;
// if(inD[i] == 0){
// queue.offer(i);
// }
// }
// }
// // 4.最后将答案移到result,因为题目要求输出List<List<Integer>>
// for(int i = 0;i < n;i++){
// result.get(i).addAll(quchong.get(i));
// }
// return result;
// }
// 方法二:dfs 速度:48ms
public List<List<Integer>> getAncestors(int n, int[][] edges) {
// 这个骚操作可以速度增加10ms,我也不知道为啥,看的大佬的题解,我本来写的是List<List<Integer>> am 速度58ms
List<Integer>[] am = new List[n];
List<List<Integer>> result = new ArrayList<>();
// 邻接矩阵
for(int i = 0;i < n;i++){
am[i] = new ArrayList<>();
result.add(new ArrayList<>());
}
for(int[] i : edges){
am[i[0]].add(i[1]);
}
// 深度遍历,反向查找
for(int i = 0;i < n;i++){
dfs(i,i,new boolean[n],result,am);
}
return result;
}
public void dfs(int pre,int cur,boolean[] isV,List<List<Integer>> result,List<Integer>[] am){
if(!isV[cur]){
isV[cur] = true;
if(pre != cur){
result.get(cur).add(pre);
}
for(int i : am[cur]){
dfs(pre,i,isV,result,am);
}
}
}
}