public class Solution {
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
List<Integer> res = new ArrayList<>();
List<List<Integer>> graph = new ArrayList<>();
int[] degrees = new int[n];
int count = n;
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
for (int[] edge : edges) {
graph.get(edge[0]).add(edge[1]);
graph.get(edge[1]).add(edge[0]);
degrees[edge[0]]++;
degrees[edge[1]]++;
}
//find leaves
for (int i = 0; i < n; i++) {
if (degrees[i] <= 1) {
queue.add(i);
count--;
}
}
while (count > 0) {
int size = queue.size();
while(size-- > 0) {
int cur = queue.poll();
for (int node: graph.get(cur)) {
degrees[node]--;
if (degrees[node] == 1) {
queue.add(node);
count--;
}
}
}
}
while(!queue.isEmpty()) res.add(queue.poll());
return res;
}
}
public class Solution {
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
List<Integer> entry = new ArrayList<>();
if( n == 1) {
entry.add(0);
return entry;
}
List<Set<Integer>> list = new ArrayList<>();
for( int i = 0 ; i < n ; i++ ){
list.add(new HashSet<>());
}
for( int[] edge : edges ){
list.get(edge[0]).add(edge[1]);
list.get(edge[1]).add(edge[0]);
}
for( int i = 0 ; i < n ; i++ ){
if( list.get(i).size() == 1 ) entry.add(i);
}
int count = n;
while( count > 2 ){
count -= entry.size();
List<Integer> newEntry = new ArrayList<>();
for( int i : entry ){
int j = list.get(i).iterator().next();
list.get(j).remove(i);
if( list.get(j).size() == 1 ){
newEntry.add(j);
}
}
entry = newEntry;
}
return entry;
}
}
public class Solution {
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
List<List<Integer>> adjList = new ArrayList<>();
for (int i = 0; i < n; i++) {
adjList.add(new ArrayList<Integer>());
}
for (int[] e : edges) {
adjList.get(e[0]).add(e[1]);
adjList.get(e[1]).add(e[0]);
}
int[] degree = new int[n];
for (int i = 0; i < n; i++) {
degree[i] = adjList.get(i).size();
}
for (int remain = n; remain > 2;) {
List<Integer> del = new ArrayList<>();
for (int j = 0; j < n; j++) {
if (degree[j] == 1) {
remain--;
del.add(j);
degree[j] = -1;
}
}
for (int node : del) {
for(int neigh : adjList.get(node)) {
degree[neigh]--;
}
}
}
List<Integer> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (degree[i] >= 0) {
res.add(i);
}
}
return res;
}
}
public class Solution {
private int dfs(List<List<Integer>> adjList, int root, boolean[] visited) {
visited[root] = true;
int height = 0;
for (int next : adjList.get(root)) {
if (!visited[next]) {
int temp = dfs(adjList, next, visited);
height = Math.max(height, temp);
}
}
return 1 + height;
}
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
List<List<Integer>> adjList = new ArrayList<>();
for (int i = 0; i < n; i++) {
adjList.add(new ArrayList<Integer>());
}
for (int[] e : edges) {
adjList.get(e[0]).add(e[1]);
adjList.get(e[1]).add(e[0]);
}
int[] heights = new int[n];
for (int i = 0; i < n; i++) {
boolean[] visited = new boolean[n];
heights[i] = dfs(adjList, i, visited);
}
int min = n + 1;
List<Integer> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (heights[i] < min) {
res.clear();
res.add(i);
min = heights[i];
} else if (heights[i] == min) {
res.add(i);
}
}
return res;
}
}