赞
踩
难度 中等
有 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]
这道题也是一道经典的图论题目,就是套深搜或广搜的模板就行。除了上面两种方法,其实并查集也是一个好的解题方法。
class Solution { public int findCircleNum(int[][] isConnected) { int c = isConnected.length;//矩阵维度 boolean[] visit = new boolean[c];//访问数组 int count = 0;//记录变量 for(int i = 0; i < c; i++){//行遍历 if(!visit[i]){//该节点没有访问过 count++; dfs(isConnected, visit, i);//深搜处理该节点 } } return count; } void dfs(int[][] isConnected, boolean[] visit, int x){//深搜处理该节点 for(int i = 0; i < isConnected[0].length; i++){ if(isConnected[x][i] == 1 && !visit[i]){//遍历相邻节点 visit[i] = true;//把相邻节点置为访问节点 dfs(isConnected, visit, i);//深搜处理该节点 } } } }
class Solution { public int findCircleNum(int[][] isConnected) { int r = isConnected.length;//矩阵维度 int count = 0;//记录变量 boolean[] visit = new boolean[r];//该节点是否遍历过 Queue<Integer> queue = new LinkedList<Integer>();//广搜辅助队列 for(int i = 0; i < r; i++){ if(!visit[i]){//没有遍历过 count++; queue.offer(i);//入队 while(!queue.isEmpty()){//队列不为空 int j = queue.poll();//出队 visit[j] = true;//置为true for(int k = 0; k < r; k++){ if(isConnected[j][k] == 1 && !visit[k]){//遍历相连节点 queue.offer(k); } } } } } return count; } }
并查集在有些图相关问题上也是可解的,比如这道题是寻找省份数量,就是有多少个集合,通过并查集也可以去解题。也建议大家学一下并查集的模板,大概即使一个步骤:
class Solution { public int findCircleNum(int[][] isConnected) { int c = isConnected.length;//矩阵维度 int[] parent = new int[c];//父节点数组 for(int i = 0; i < c; i++){//1、初始化父节点为本身 parent[i] = i; } for(int i = 0; i < c; i++){//行遍历 for(int j = i + 1; j < c; j++){//列遍历 if(isConnected[i][j] == 1){//相连 union(parent, i, j);//合并父节点 } } } int count = 0; for(int i = 0; i < c; i++){//4、判断集合数量 if(parent[i] == i){//每个集合只有一个根节点,如果父节点等于本身,就代表一个集合 count++; } } return count; } int find(int[] parent, int x){//2、寻找父节点 return x == parent[x] ? x : find(parent, parent[x]); } void union(int[] parent, int index1, int index2){//3、合并父节点 parent[find(parent, index1)] = find(parent, index2); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。