/**
Minimum Height Trees
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.
Example 1:
Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/ \
2 3
return [1]
Example 2:
Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2
\ | /
3
|
4
|
5
return [3, 4]
*/
/**
For leaf nodes, their degree = 1, which means each of them is only connected to one node.
In our loop, each time we delete the leaf nodes from our graph(just by putting their degrees to 0), and meanwhile we add the new leaf nodes after deleting them(just add their connected nodes with degree as 2) to the queue.
So basically in the end, the nodes in the queue would be connected to no other nodes but each other. They should be the answer.
*/
public class MinimumHeightTree{
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
List<List<Integer>> myGraph = new ArrayList<List<Integer>>();
List<Integer> res = new ArrayList<Integer>();
if (n==1) {
res.add(0);
return res;
}
int[] degree = new int[n];
for(int i=0; i<n; i++) {
myGraph.add(new ArrayList<Integer>());
}
for(int i=0; i<edges.length; i++) {
myGraph.get(edges[i][0]).add(edges[i][1]);
myGraph.get(edges[i][1]).add(edges[i][0]);
degree[edges[i][0]]++;
degree[edges[i][1]]++;
}
Queue<Integer> myQueue = new ArrayDeque<Integer>();
for(int i=0; i<n; i++){
if (degree[i]==0)
return res;
else if (degree[i]==1) {//add the nodes with only degree 1
myQueue.offer(i);
}
}
while (!myQueue.isEmpty()) {
res = new ArrayList<Integer>();
int count = myQueue.size();
for(int i=0; i<count; i++){
int curr = myQueue.poll();
res.add(curr);
degree[curr]--;
//for the adjacent nodes of this node, reduce the degree by 1
for(int k=0; k<myGraph.get(curr).size(); k++) {
int next = myGraph.get(curr).get(k);
if (degree[next]==0) continue;
if (degree[next]==2) {
myQueue.offer(next);
}
degree[next]--;
}
}
}
return res;
}
}
Minimum Height Trees
For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write a function to find all the MHTs and return a list of their root labels.
The graph contains n nodes which are labeled from 0 to n - 1. You will be given the number n and a list of undirected edges (each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.
Example 1:
Given n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/ \
2 3
return [1]
Example 2:
Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
0 1 2
\ | /
3
|
4
|
5
return [3, 4]
*/
/**
For leaf nodes, their degree = 1, which means each of them is only connected to one node.
In our loop, each time we delete the leaf nodes from our graph(just by putting their degrees to 0), and meanwhile we add the new leaf nodes after deleting them(just add their connected nodes with degree as 2) to the queue.
So basically in the end, the nodes in the queue would be connected to no other nodes but each other. They should be the answer.
*/
public class MinimumHeightTree{
public List<Integer> findMinHeightTrees(int n, int[][] edges) {
List<List<Integer>> myGraph = new ArrayList<List<Integer>>();
List<Integer> res = new ArrayList<Integer>();
if (n==1) {
res.add(0);
return res;
}
int[] degree = new int[n];
for(int i=0; i<n; i++) {
myGraph.add(new ArrayList<Integer>());
}
for(int i=0; i<edges.length; i++) {
myGraph.get(edges[i][0]).add(edges[i][1]);
myGraph.get(edges[i][1]).add(edges[i][0]);
degree[edges[i][0]]++;
degree[edges[i][1]]++;
}
Queue<Integer> myQueue = new ArrayDeque<Integer>();
for(int i=0; i<n; i++){
if (degree[i]==0)
return res;
else if (degree[i]==1) {//add the nodes with only degree 1
myQueue.offer(i);
}
}
while (!myQueue.isEmpty()) {
res = new ArrayList<Integer>();
int count = myQueue.size();
for(int i=0; i<count; i++){
int curr = myQueue.poll();
res.add(curr);
degree[curr]--;
//for the adjacent nodes of this node, reduce the degree by 1
for(int k=0; k<myGraph.get(curr).size(); k++) {
int next = myGraph.get(curr).get(k);
if (degree[next]==0) continue;
if (degree[next]==2) {
myQueue.offer(next);
}
degree[next]--;
}
}
}
return res;
}
}
No comments:
Post a Comment