Leetcode 547.省份数量

这篇文章介绍了如何使用队列模拟搜索和并查集算法解决LeetCode题目547,即计算给定城市网络中省份的数量。通过遍历矩阵,利用连通分量的概念,结合队列和并查集数据结构,有效地找出直接或间接相连的城市群组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Leetcode 547.省份数量

nnn个城市,其中一些彼此相连,另一些没有相连。如果城市aaa与城市 bbb直接相连,且城市 bbb与城市 ccc直接相连,那么城市 aaa与城市 ccc 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n∗nn * nnn 的矩阵 isConnectedisConnectedisConnected ,其中 isConnected[i][j]=1isConnected[i][j] = 1isConnected[i][j]=1表示第iii个城市和第 jjj个城市直接相连,而isConnected[i][j]=0isConnected[i][j] = 0isConnected[i][j]=0表示二者不直接相连。

返回矩阵中 省份 的数量。

示例 1:

输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]]
输出:2

示例 2:

输入:isConnected = [[1,0,0],[0,1,0],[0,0,1]]
输出:3

提示:

1<=n<=2001 <= n <= 2001<=n<=200
n==isConnected.lengthn == isConnected.lengthn==isConnected.length
n==isConnected[i].lengthn == isConnected[i].lengthn==isConnected[i].length
isConnected[i][j]为1或0isConnected[i][j] 为 1 或 0isConnected[i][j]10
isConnected[i][i]==1isConnected[i][i] == 1isConnected[i][i]==1
isConnected[i][j]==isConnected[j]isConnected[i][j] == isConnected[j]isConnected[i][j]==isConnected[j]

队列模拟搜索:

遇到一个没有经过的节点就把它加入队列,ans+1ans+1ans+1

然后遍历这个节点里面我们没去过的所有节点,把它们都加入队列

最后ansansans就是连通分量个数.也就是省份个数

class Solution {
public:
    int findCircleNum(vector <vector<int>> &isConnected) {
        int M[210] = {0};
        int ans = 0;
        int n = isConnected.size();
        queue<int> q;
        for (int k = 0; k < n; k++) {
            if (M[k] == 0) {
                q.push(k);
                ans++;
            }
            while (q.size()) {

                int i = q.front();
                q.pop();
                if (M[i]) continue;
                int m = isConnected[i].size();
                M[i] = 1;
                for (int j = 0; j < m; j++) {
                    if (isConnected[i][j] == 1 && M[j] == 0) {
                        q.push(j);
                    }
                }
            }
        }
        return ans;
    }
};

在这里插入图片描述

并查集:

先遍历一遍数组,把所有相连的省份连接起来

最后再遍历一遍有多少个不相同的父节点就是有多少个连通分量

class Solution {
public:
    int f[210];

    int fa(int n) {
        if (f[n] == n) return n;
        return f[n] = fa(f[n]);
    }

    void connect(int x, int y) {
        int fx = fa(x);
        int fy = fa(y);
        if (fx > fy) {
            f[fy] = fx;
        } else {
            f[fx] = fy;
        }
    }

    int findCircleNum(vector <vector<int>> &isConnected) {
        int n = isConnected.size();
        for (int i = 0; i <= n; i++) f[i] = i;
        int ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i != j && isConnected[i][j]) {
                    connect(i, j);
                }
            }
        }
        int Is[210] = {0};
        for (int i = 0; i < n; i++) {
            if (Is[fa(i)] == 0) {
                Is[fa(i)]++;
                ans++;
            }
        }
        return ans;
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值