1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| class Solution { public List<List<Integer>> getAncestors(int n, int[][] edges) { // 标记已经计算完成的节点 boolean[] visit = new boolean[n]; // 反方向建立联系 Map<Integer, List<Integer>> relations = new HashMap<>(n); for (int[] edge : edges) { relations.merge(edge[1], Collections.singletonList(edge[0]), (origin, target) -> { if (origin.size() == 1) { origin = new ArrayList<>(origin); } origin.addAll(target); return origin; }); } List<List<Integer>> ans = new ArrayList<>(n); for (int i = 0; i < n; i++) { ans.add(new ArrayList<>()); } // 循环计算每个节点 for (int i = 0; i < n; i++) { this.dfs(i, visit, relations, ans); } return ans; }
private List<Integer> dfs(int cur, boolean[] visit, Map<Integer, List<Integer>> relations, List<List<Integer>> ans) { if (visit[cur]) { return ans.get(cur); } // 标记当前节点已计算完毕 visit[cur] = true; // 记录当前节点的所有父节点,可能会有节点重复 List<Integer> parent = new ArrayList<>(); for (Integer relation : relations.getOrDefault(cur, Collections.emptyList())) { parent.addAll(this.dfs(relation, visit, relations, ans)); parent.add(relation); } if (parent.isEmpty()) { return parent; } // 排序 Collections.sort(parent); // 双指针去重 int i = 0; int n = parent.size(); for (int j = 1; j < n; j++) { if (!Objects.equals(parent.get(j), parent.get(i))) { parent.set(++i, parent.get(j)); } } ans.set(cur, parent.subList(0, i + 1)); return parent; } }
|