日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决

發布時間:2024/7/5 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題來源

此題來源于LeetCode547. Friend Circles,主要運用了并查集(union find)、廣度優先遍歷(bfs)和深度優先遍歷(bfs)三種方法解決。

問題簡述

給定一個N×N的矩陣M表示了N個人之見的朋友關系。如果M[i][j]=1那么ij是直接朋友關系;如果M[i][j]=1M[j][k]=1M[i][k]=0,那么ik是間接朋友關系。我們假定有直接和間接朋友關系的人為一個朋友圈,試問M中有幾個朋友圈。
比如:

輸入: [[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的速度差不多,三者也許都還有優化的余地~

    總結

    以上是生活随笔為你收集整理的LeetCode547. Friends Circles 利用union find | bfs | dfs三种方法解决的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。