IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode: 547. 省份数量 -> 正文阅读

[数据结构与算法]leetcode: 547. 省份数量

547. 省份数量

来源:力扣(LeetCode)

链接: https://leetcode.cn/problems/number-of-provinces/

n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

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

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[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 <= 200
  • n == isConnected.length
  • n == isConnected[i].length
  • isConnected[i][j] 为 1 或 0
  • isConnected[i][i] == 1
  • isConnected[i][j] == isConnected[j][i]

解法

  • DFS: 这个与岛屿问题有些类似,但是区别是间隔也可以是有联系的,isConnected[i][j]表示第i个城市与第j个城市有关联,另外关联是可以传递的,不像岛屿问题只看周边就行,因此这里dfs是以层 列为参数进行递归,矩阵的第i行表示第i个城市,第j列表示第j个城市,这里需要使用一个集合visited表示城市是否被访问过
  • 并查集+联通区域:使用并查集添加城市,将有关联的城市联通起来,最后统计联通区域有多少即可

代码实现

DFS

python实现

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        cities = len(isConnected)
        count = 0
        visited = set()

        def dfs(i: int):
            for j in range(cities):
                if isConnected[i][j] == 1 and j not in visited:
                    visited.add(j)
                    dfs(j)
        
        for i in range(cities):
            if i not in visited:
                count += 1
                dfs(i)
        return count

c++实现

class Solution {
public:
    void dfs(vector<vector<int>>& isConnected, set<int>& visited, int cities, int i) {
        for (int j = 0; j < cities; j++) {
            if (isConnected[i][j] == 1 && visited.find(j) == visited.end()) {
                visited.insert(j);
                dfs(isConnected, visited, cities, j);
            }
        }
    }

    int findCircleNum(vector<vector<int>>& isConnected) {
        int cities = isConnected.size();
        set<int> visited;
        int count = 0;
        for (int i = 0; i < cities; i++) {
            if (visited.find(i) == visited.end()) {
                count++;
                dfs(isConnected, visited, cities, i);
            }
        }
        return count;
    }
};

复杂度分析

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)
  • 空间复杂度: O ( n ) O(n) O(n)

并查集

python实现

class UnionFind:
    def __init__(self):
        self.father = {}
        self.num_of_sets = 0
    
    def add(self, x):
        if x not in self.father:
            self.father[x] = None
            self.num_of_sets += 1
    
    def find(self, x):
        root = x
        while self.father[root] != None:
            root = self.father[root]
        
        while x != root:
            origin_father = self.father[x]
            self.father[x] = root
            x = origin_father
        return root

    def merge(self, x, y):
        root_x = self.find(x)
        root_y = self.find(y)
        if root_x != root_y:
            self.father[root_x] = root_y
            self.num_of_sets -= 1

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        m = len(isConnected)
        uf = UnionFind()
        for i in range(m):
            uf.add(i)
            for j in range(i):
                if isConnected[i][j]:
                    uf.merge(i, j)
        return uf.num_of_sets

c++实现

class UnionFind:
    def __init__(self):
        self.father = {}
        self.num_of_sets = 0
    
    def add(self, x):
        if x not in self.father:
            self.father[x] = None
            self.num_of_sets += 1
    
    def find(self, x):
        root = x
        while self.father[root] != None:
            root = self.father[root]
        
        while x != root:
            origin_father = self.father[x]
            self.father[x] = root
            x = origin_father
        return root

    def merge(self, x, y):
        root_x = self.find(x)
        root_y = self.find(y)
        if root_x != root_y:
            self.father[root_x] = root_y
            self.num_of_sets -= 1

class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        m = len(isConnected)
        uf = UnionFind()
        for i in range(m):
            uf.add(i)
            for j in range(i):
                if isConnected[i][j]:
                    uf.merge(i, j)
        return uf.num_of_sets

复杂度分析

  • 时间复杂度: O ( n 2 l o g n ) O(n^2logn) O(n2logn)
  • 空间复杂度: O ( n ) O(n) O(n)

参考

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:59:49  更:2022-10-17 13:02:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:49:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码