对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。
格式
该图包含 n 个节点,标记为 0 到 n - 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。
你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里。
示例 1:
输入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
0
|
1
/ \
2 3
输出: [1]
分析:
这个问题我写了两种方法,都是广度优先,一层一层剥开。
1 以每个点为起点计算它的高度。curQue表示当前队列,nextQue表示下一层的队列,一层一层往下剥开,计算高度,当对n个点分别求出高度之后,就可以比较得出结果了
2我们寻找度为1的结点,一层一层删除,这里就需要先扫描edges,先统计度,并建立邻接表。然后curQue表示最外层,nextQue表示里面一层,当撕开到最后一层的时候,会存在一到两个结点,注意判断条件,并设置isVisit
class Solution {
public:
struct cmp{
bool operator()(const pair<int,int> left, const pair<int,int> right)
{
return left.second>right.second;
}
};
int calHeight(int cur,vector<vector<int>> recordVec,vector<bool> isVisit)
{
queue<int> myQue;
myQue.push(cur);
isVisit[cur] = true;
int total = 0;
while(!myQue.empty())
{
total ++;
queue<int> nextQue;
while(!myQue.empty())
{
int topNum = myQue.front();
myQue.pop();
for(int i=0;i<recordVec[topNum].size();i++)
{
if(!isVisit[recordVec[topNum][i]])
{
nextQue.push(recordVec[topNum][i]);
isVisit[recordVec[topNum][i]] = true;
}
}
}
myQue = nextQue;
}
return total;
}
vector<int> findV1(int n, vector<vector<int>> edges)
{
vector<int> last;
if(n==0)
return last;
vector<vector<int>> recordVec(n);
for(int i=0;i<edges.size();i++){
vector<int> tempVec = edges[i];
recordVec[tempVec[0]].push_back(tempVec[1]);
recordVec[tempVec[1]].push_back(tempVec[0]);
}
vector<bool> isVisit(n,false);
priority_queue<pair<int,int>,vector<pair<int,int>>, cmp> res;
for(int i=0;i<n;i++)
{
int temp = calHeight(i,recordVec,isVisit);
res.push(pair<int,int>(i,temp));
}
pair<int,int> top = res.top();
res.pop();
last.push_back(top.first);
while(!res.empty())
{
pair<int,int> temp = res.top();
res.pop();
if(top.second==temp.second)
last.push_back(temp.first);
else
break;
}
return last;
}
vector<int> deleteOut(int n,vector<vector<int>> edges)
{
vector<int> last;
if(n==0)
return last;
if(n==1){
last.push_back(0);
return last;
}
if(n==2)
{
last.push_back(0);
last.push_back(1);
return last;
}
vector<vector<int>> adList(n);
vector<int> degree(n,0);
for(int i=0;i<edges.size();i++){
vector<int> temp = edges[i];
adList[temp[0]].push_back(temp[1]);
adList[temp[1]].push_back(temp[0]);
degree[temp[0]]++;
degree[temp[1]]++;
}
vector<bool> isVisit(n,false);
queue<int> myQue;
int total = n;
for(int i=0;i<n;i++){
if(degree[i]<=1)
{
myQue.push(i);
isVisit[i] = true;
}
}
while(!myQue.empty())
{
if(total<=2)
{
while(!myQue.empty())
{
last.push_back(myQue.front());
myQue.pop();
}
break;
}
queue<int> nextQue;
while(!myQue.empty())
{
int topNum = myQue.front();
myQue.pop();
total--;
for(int i=0;i< adList[topNum].size();i++)
{
int index = adList[topNum][i];
if(!isVisit[index])
{
degree[index]--;
if(degree[index]<=1)
{
nextQue.push(index);
isVisit[index] = true;
}
}
}
}
myQue = nextQue;
}
return last;
}
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
vector<int> res = deleteOut(n,edges);
return res;
}
};