List<Integer> ans = new ArrayList<>(); if (n<=2){ for (int i = 0; i < n; i++) { ans.add(i); } return ans; }
统计入度情况,生成连接图
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 入度数组 int[] inDegre = newint[n]; // 存储edges Set<Integer>[] adjs = new Set[n]; for (int i = 0; i < n; i++) { adjs[i] = new HashSet<>(); }
for (int[] edge:edges){ adjs[edge[0]].add(edge[1]); adjs[edge[1]].add(edge[0]); inDegre[edge[0]]++; inDegre[edge[1]]++; }
用队列记录入度为 1 的点
1 2 3 4 5 6 7
// 记录入度为1的点 Queue<Integer> queue = new LinkedList<>(); for (int i = 0; i < n; i++) { if (inDegre[i]==1){ queue.add(i); } }
然后迭代,直至节点数小于等于2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
while (n>2){ int size = queue.size(); // 减小 n n-=size; for (int i = 0; i < size; i++) { int top = queue.poll(); // 将当前点标记为删除 result[top] = true; // 把它和它的邻接节点入度减一 inDegre[top] -=1; Set<Integer> set = adjs[top]; for (Integer s:set){ inDegre[s]-=1; if (inDegre[s]==1){ queue.offer(s); } } } }
最后遍历结果记录数组
1 2 3 4 5
for (int i = 0; i < result.length; i++) { if (!result[i]){ ans.add(i); } }
public List<Integer> findMinHeightTrees(int n, int[][] edges){ List<Integer> ans = new ArrayList<>(); if (n<=2){ for (int i = 0; i < n; i++) { ans.add(i); } return ans; } // 入度数组 int[] inDegre = newint[n]; // 记录是否被 pass,如果 pass,则为 true boolean[] result = newboolean[n]; // 存储edges Set<Integer>[] adjs = new Set[n]; for (int i = 0; i < n; i++) { adjs[i] = new HashSet<>(); }
for (int[] edge:edges){ adjs[edge[0]].add(edge[1]); adjs[edge[1]].add(edge[0]); inDegre[edge[0]]++; inDegre[edge[1]]++; } // 记录入度为1的点 Queue<Integer> queue = new LinkedList<>(); for (int i = 0; i < n; i++) { if (inDegre[i]==1){ queue.add(i); } } while (n>2){ int size = queue.size(); n-=size; for (int i = 0; i < size; i++) { int top = queue.poll(); result[top] = true; // 把它和它的邻接节点入度减一 inDegre[top] -=1; Set<Integer> set = adjs[top]; for (Integer s:set){ inDegre[s]-=1; if (inDegre[s]==1){ queue.offer(s); } } } } for (int i = 0; i < result.length; i++) { if (!result[i]){ ans.add(i); } } return ans; }