• leetcode之路:547. 省份数量


    • 城市和城市连在一块,有多少个省?

    • 一群人里面自己和自己亲戚连在一块,有多少组亲戚?

    • 你俩是不是一个小区的?

    • 他俩是不是有一腿

    以上所有问题,抽象,概括为分组问题

    老并查集了

    这里引用一个知乎大佬的并查集讲解,gang的非常好,我就不赘述了。

    并查集讲解

    大家主要了解一下并查集的两种优化方法,路径压缩使得所有节点在被查询过后都直接连在根节点上(这样下次查询的时候就可以O(1)查到他属于哪个组),按深度合并分组可以保证树的深度不会过分增长。

    这个题可谓练手并查集的好题目
    代码如下
    class Solution {
    private:
        const static int maxn = 200 + 5;
        int fa[maxn], depth[maxn];
    
        /**
        * 初始化根节点数组,深度数组
        */
        void init(){
            for(int i = 0; i < maxn; i++){
                fa[i] = i;
                depth[i] = 1;
            }
        }
    
        /**
        * 找到某个节点的根节点(他属于哪一组?)
        */
        int find(int x){
            return (x == fa[x]) ? fa[x] : (fa[x] = find(fa[x]));
        }
    
        /**
        * 合并两个分组
        */
        void merge(int a, int b){
            int x = find(a), y = find(b);
            if(depth[x] > depth[y])fa[y] = x;
            if(depth[y] > depth[x])fa[x] = y;
            if(depth[x] == depth[y] && x != y){
                fa[x] = y;
                depth[y] ++;
            }
        }
    public:
        int findCircleNum(vector<vector<int>>& isConnected) {
            init();
            int n = isConnected.size();
            for(int i = 0; i < n; i++){
                for(int j = i + 1; j < n; j++){
                    if(i != j && isConnected[i][j]){
                        merge(i, j);
                    }
                }
            }
            set<int>ans;
            for(int i = 0; i < n; i++)ans.insert(find(i));//set去一下重,查一下有多少个不同的分组就是多少个省了
            return ans.size();
        }
    };
    
  • 相关阅读:
    POJ1659:Frogs' Neighborhood(图论)
    POJ1659:Frogs' Neighborhood(图论)
    zzuli2504: 建国的签到活动二(dfs)
    zzuli2504: 建国的签到活动二(dfs)
    zzuli2506: 建勋的魔法学院
    zzuli2506: 建勋的魔法学院
    趣学算法:沟通无限校园网 (最小生成树)
    cocoapods的使用
    MJExtension的使用
    类别
  • 原文地址:https://www.cnblogs.com/peichaoL/p/14244967.html
Copyright © 2020-2023  润新知