20230724-复习-拓扑排序+并查集

36 阅读1分钟

leetcode-547 省份数量

没啥好说的,并查集模板题。我感觉并查集的精髓就体现在find和merge两个函数的递归操作里。

class Solution {
public:
    int fa[200];
    void init(int n){
        for(int i = 0; i < n; ++i) fa[i] = i;
    }

    int find(int x){
        return x == fa[x] ? x : (fa[x] = find(fa[x]));
    }

    void merge(int x, int y){
        fa[find(x)] = find(y);
    }
    int findCircleNum(vector<vector<int>>& isConnected) {
        int n = isConnected.size();
        init(n);
        for(int i = 0; i < n; ++i){
            for(int j = i + 1; j < n; ++j){
                if(isConnected[i][j] == 1) merge(i, j);
            }
        }
        int ans = 0;
        for(int i = 0; i < n; ++i){
            if(fa[i] == i) ++ans;
        }
        return ans;
    }
};

leetcode-310 最小高度树

这道题思路就是从度为1的节点开始一层一层剥洋葱,跟拓扑排序基本一样。

需要想一下的点:

  • 首先树是无向图,而无向图其实也就是双向图,一条边的两个节点都需要统计到。
  • 其次是按照思路一层层剥下去,但并没有一个明显的停止条件,满足达到这个停止条件之后树中剩下的节点都是结果。因此需要用一个结果集每一“层”暂存当前节点,每次进入循环则清空——当不满足进入循环的条件,也就是该结束了的时候,结果集中剩下的就是结果。
class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        if(n == 1) return {0};
        vector<int> degree(n);
        vector<vector<int>> conn(n);
        for(auto& edge : edges){
            int a = edge[0], b = edge[1];
            conn[a].push_back(b);
            conn[b].push_back(a);
            ++degree[a];
            ++degree[b];
        }
        deque<int> q;
        for(int i = 0; i < n; ++i){
            if(degree[i] == 1) q.push_back(i);
        }
        vector<int> iteration;
        while(!q.empty()){
            iteration.clear();
            int len = q.size();
            for(int i = 0; i < len; ++i){
                int node = q.front();
                q.pop_front();
                iteration.push_back(node);
                vector<int>& this_conn = conn[node];
                for(int nx : this_conn){
                    --degree[nx];
                    if(degree[nx] == 1) q.push_back(nx);
                }
            }
        }
        return iteration;
    }
};