逐步删除叶子节点
class Solution {
public:
struct Node
{
unordered_set<int> neighbor;
bool isLeaf()const { return neighbor.size() == 1; }
};
vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
vector<int> buffer1;
vector<int> buffer2;
vector<int>* pB1 = &buffer1;
vector<int>* pB2 = &buffer2;
if (n == 1)
{
buffer1.push_back(0);
return buffer1;
}
if (n == 2)
{
buffer1.push_back(0);
buffer1.push_back(1);
return buffer1;
}
// build the graph
vector<Node> nodes(n);
for (auto p : edges)
{
nodes[p.first].neighbor.insert(p.second);
nodes[p.second].neighbor.insert(p.first);
}
// find all leaves
for (int i = 0; i<n; ++i)
{
if (nodes[i].isLeaf()) pB1->push_back(i);
}
// remove leaves layer-by-layer
while (1)//从命名可以看出来用了双缓存的思想,好厉害
{
for (int i : *pB1)//这种书写方法很简便,学习一下
{
for (auto n : nodes[i].neighbor)
{
nodes[n].neighbor.erase(i);
//擦除第一层叶子节点的之后,检查一下和叶子节点相连的节点会不会变成叶子节点,
//如果变成了叶子节点,就把这个节点加入二级缓存PB2里
if (nodes[n].isLeaf()) pB2->push_back(n);
}
}
if (pB2->empty())
{
return *pB1;
}
pB1->clear();//清空缓存1
swap(pB1, pB2);//交换两个缓存
}
}
};