LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决
生活随笔
收集整理的這篇文章主要介紹了
LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題來源
此題來源于LeetCode547. Friend Circles,主要運用了并查集(union find)、廣度優先遍歷(bfs)和深度優先遍歷(bfs)三種方法解決。
問題簡述
給定一個N×N的矩陣M表示了N個人之見的朋友關系。如果M[i][j]=1那么i和j是直接朋友關系;如果M[i][j]=1,M[j][k]=1,M[i][k]=0,那么i和k是間接朋友關系。我們假定有直接和間接朋友關系的人為一個朋友圈,試問M中有幾個朋友圈。
比如:
又比如:
輸入: [[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的速度差不多,三者也許都還有優化的余地~
總結
以上是生活随笔為你收集整理的LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 1877. 数组中最大
- 下一篇: HiveQL: 数据定义