[LeetCode] 547. Friend Circles 朋友圈
本题可以套用和 [LeetCode] 200. Number of Islands 岛屿的数量 与 [LeetCode 695] Max Area of Island 岛的最大面积一样的dfs模版,不同的是DFS的遍历路径不同,本题
采用的是类似十字遍历方式,具体见如下代码。
1 /* 2 * @Descripttion: 3 * @version: 4 * @Author: wangxf 5 * @Date: 2019-12-20 15:21:49 6 * @LastEditors: Do not edit 7 * @LastEditTime: 2020-04-12 23:25:24 8 */ 9 /* 10 * @lc app=leetcode.cn id=547 lang=cpp 11 * 12 * [547] 朋友圈 13 */ 14 15 // @lc code=start 16 #include<bits/stdc++.h> 17 using namespace std; 18 class Solution { 19 public: 20 int findCircleNum(vector<vector<int>>& M) 21 { 22 int res = 0; 23 if(M.empty()||M.size()<=0) return 0; 24 for (size_t i = 0; i < M.size(); i++) 25 for (size_t j = 0; j < M[0].size(); j++) 26 { 27 /* 28 if(i==j) 29 { 30 //++res; 31 continue; 32 } 33 */ 34 if(M[i][j]==1) 35 { 36 ++res; 37 dfs(M,i,j); 38 } 39 } 40 return res; 41 } 42 void dfs(vector<vector<int>>& M,int i,int j) 43 { 44 if(!(i>=0&&i<M.size()&&j>=0&&j<M[0].size())) 45 { 46 return; 47 } 48 if(M[i][j]==0) 49 { 50 return; 51 } 52 M[i][j]=0; 53 //if(i==j) return; 54 55 for(int r = 0;r<M.size();++r) 56 { 57 if(M[r][j]==1&&r!=i) 58 { 59 dfs(M,r,j); 60 } 61 } 62 for(int c = 0;c<M[0].size();++c) 63 { 64 if(M[i][c]==1&&c!=j) 65 { 66 dfs(M,i,c); 67 } 68 } 69 return; 70 } 71 }; 72 // @lc code=end
本题同样可以并查集的方法解决。代码如下:
/* * @Descripttion: * @version: * @Author: wangxf * @Date: 2019-12-20 15:21:49 * @LastEditors: Do not edit * @LastEditTime: 2020-04-14 19:49:27 */ /* * @lc app=leetcode.cn id=547 lang=cpp * * [547] 朋友圈 */ // @lc code=start #include<bits/stdc++.h> using namespace std; //union find 算法 class UF { public: // 构造函数初始化 UF(int n) { count = n; parent.resize(n); size.resize(n); for(int i = 0; i < n; i++) { parent[i] =i; size[i] = 1; } } // 将节点p 和 节点 q 连通 void Union(int p, int q) { int rootP = find(p); int rootQ = find(q); if(rootP == rootQ) return; if(size[rootP] > size[rootQ]) { parent[rootQ] = rootP; size[rootP] += size[rootQ]; } else { parent[rootP] = rootQ; size[rootQ] += rootP; } count--;//连通个数 -1 } //判断节点p 和 节点 q 是否连通 bool connected(int p, int q) { int rootP = find(p); int rootQ = find(q); return rootP==rootQ; } //返回当前连通个数 int count_num() { return count; } private: int count;//连通的个数 vector<int> parent;//保存节点的父节点 vector<int> size;//保存节点所在连通分量的重量(节点数) int find(int x)// 寻找 x 节点的根点 { while(parent[x] != x) { //查找根节点的同时,对树进行路径压缩, parent[x] = parent[parent[x]]; x = parent[x]; } return x; } }; class Solution { public: int findCircleNum(vector<vector<int>>& M) { // base case if(M.size()==0) return 0; const int m = M.size();//行数 const int n = M[0].size();//列数 //UF* uf = new UF(m); UF uf(m); for(int i = 0; i < m; i++) { for(int j = i+1; j < n; j++)//表示朋友圈的矩阵是对称的 { if(M[i][j] == 1) { uf.Union(i,j); } } } return uf.count_num(); } }; // @lc code=end
---------------------------- ------------------------------参考链接---------------------------------------------------------------------------
感谢:
通俗理解并查集:https://blog.csdn.net/niushuai666/article/details/6662911