LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决
来源:互联网 发布:淘宝上找货源 编辑:程序博客网 时间:2024/06/01 20:26
问题来源
此题来源于LeetCode547. Friend Circles,主要运用了并查集(union find)、广度优先遍历(bfs)和深度优先遍历(bfs)三种方法解决。
问题简述
给定一个
比如:
输入: [[1,1,0], [1,1,0], [0,0,1]]输出: 2解释:第0和第1个人是直接朋友,他们构成1个朋友圈;第2个人自己构成一个朋友圈,所以返回2。
又比如:
输入: [[1,1,0], [1,1,1], [0,1,1]]输出: 1解释:第0和第1个人是直接朋友,第1和第2个人是直接朋友,所以第0和第2个人是间接朋友,这3个人构成了1个朋友圈,所以返回1。
值得注意的是:
- 总是有
M[i][j]=M[j][i] - 总是有
M[i][i]=1
解决方案
利用union find解决
此处的并查集用到了路径压缩的优化。
class Solution {private: vector<int> vec; int sz;private: void Initialize(int count){ vec = vector<int>(count); sz = count; for (int i = 0; i < count; i++) vec[i] = i; } int findRoot(int p){ assert(p >= 0 && p < sz); while (vec[p] != p){ //路径压缩 vec[p] = vec[vec[p]]; p = vec[p]; } return vec[p]; } void unionNode(int p, int q){ assert(p >= 0 && p < sz && q >= 0 && q < sz); int pRoot = findRoot(p); int qRoot = findRoot(q); if (pRoot != qRoot) vec[pRoot] = qRoot; }public: int findCircleNum(vector<vector<int>>& M) { int m = M.size(); if (0 >= m) return 0; Initialize(m); for (int i = 0; i < m; i++){ for (int j = i + 1 ; j < m; j++){ if (M[i][j] == 1) unionNode(i, j); } } int res = 0; for (int i = 0; i < m; i++) if (vec[i] == i) res++; return res; }};
利用bfs解决
由于问题的特殊性,每次都只要把对角线上的元素放到队列当中即可。
class Solution {private: int sz;private: void bfs(vector<vector<int>> &M, int x){ queue<int> q; q.push(x); while(!q.empty()){ int newX = q.front(); q.pop(); M[newX][newX] = 0; for (int i = 0; i < sz; i++){ if (1 == M[newX][i]){ M[newX][i] = 0; M[i][newX] = 0; if (1 == M[i][i]) q.push(i); } } } return; }public: int findCircleNum(vector<vector<int>>& M) { int m = M.size(); if (0 >= m) return 0; sz = m; int res = 0; for (int i = 0; i < m; i++){ if (1 == M[i][i]){ bfs(M,i); res++; } } return res; }};
利用dfs解决
dfs与bfs的思路大同小异,但元素过多可能会造成栈溢出。
class Solution {private: int sz;private: void dfs(vector<vector<int>> &M, int x, int y){ if (0 == M[x][y]) return; M[x][y] = 0; for (int i = 0; i < sz; i++){ if (1 == M[x][i]){ M[x][i] = 0; M[i][x] = 0; dfs(M, i, i); } } return; }public: int findCircleNum(vector<vector<int>>& M) { int m = M.size(); if (0 >= m) return 0; sz = m; int res = 0; for (int i = 0; i < m; i++){ if (1 == M[i][i]){ dfs(M,i,i); res++; } } return res; }};
结束语
以上三种方法最快的是并查集(union find),bfs和dfs的速度差不多,三者也许都还有优化的余地~
阅读全文
0 0
- LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决
- hdu 2952 dfs|bfs|union-find sets
- leetcode547. Friend Circles
- 第十五周:( LeetCode547) Friend Circles(c++)
- 130. Surrounded Regions 将包围的符号变换 BFS & DFS & UNION find
- 利用BFS和DFS解决 LeetCode 130: Surrounded Regions
- dfs+bfs(三种路径问题)
- POJ-1426-Find The Multiple (BFS +DFS)两种解法
- EOJ 1816 判断图连通的三种方法——dfs,bfs,并查集
- 【leetcode】104. Maximum Depth of Binary Tree【java】三种实现方法:递归、BFS、DFS
- 1014. Circles of Friends (35)
- 1014. Circles of Friends (35)
- DFS/BFS解决宝岛探险
- poj 1426 Find The Multiple (bfs / dfs)
- POJ1426 Find The Multiple (BFS | DFS)
- poj Find The Multiple(DFS,BFS)
- 迷宫系列(三)利用BFS/DFS的数据得到最短路/通路
- 【PAT-T】1014. Circles of Friends (35)
- ThinkInJava(Java编程思想总结)2017.8.9-------操作符
- I Hate It---线段树
- C++中参数传递的两种方式:传值与传址及它们的区别
- nginx.conf配置详解
- Xamrin.Forms 用户界面——控件——Style——设备样式
- LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决
- 开启科研之路,写此文以作纪念!
- Linux 问题解决拾遗
- JAVA HttpClient(普通参数、JSON格式参数)
- Mysql读写分离实现的三种方式
- 【牛腩】LinkButton
- SQL FULL JOIN 关键字
- C语言(18)A+B Problem II
- Storm基本知识