LeetCode 547 Friend Circles(朋友圈问题)

古城微笑少年丶 2022-05-15 05:54 318阅读 0赞
题目描述:

班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道,输出所有学生中的已知的朋友圈总数。

示例 1:

输入: [ [1,1,0], [1,1,0], [0,0,1] ]
输出: 2
说明:已知学生0和学生1互为朋友,他们在一个朋友圈。

示例2:

输入: [ [1,1,0], [1,1,1], [0,1,1] ]
输出: 1
说明:已知学生0和学生1互为朋友,学生1和学生2互为朋友,所以学生0和学生2也是朋友,所以他们三个在一个朋友圈,返回1。

思路1:利用并查集的思想,将有关系的人分到一起,最后统计朋友圈的个数。
关于并查集,可以点击此处查看我以前的博客

  1. // 并查集的方法
  2. class Solution {
  3. public:
  4. int FindRoot(vector<int> &fathers, int index)
  5. {
  6. while (fathers[index] >= 0)
  7. index = fathers[index];
  8. return index;
  9. }
  10. void Union(vector<int> &fathers, int i, int j)
  11. {
  12. int root1 = FindRoot(fathers, i);
  13. int root2 = FindRoot(fathers, j);
  14. if (root1 != root2)
  15. {
  16. fathers[root1] += fathers[root2];
  17. fathers[root2] = root1;
  18. }
  19. }
  20. int Count(vector<int> &fathers)
  21. {
  22. int count = 0;
  23. for (int i = 0; i < fathers.size(); i++)
  24. {
  25. if (fathers[i] < 0)
  26. count++;
  27. }
  28. return count;
  29. }
  30. int findCircleNum(vector<vector<int>>& M)
  31. {
  32. int n = M.size();
  33. vector<int> fathers(n, 0);
  34. for (int i = 0; i < n; i++)
  35. fathers[i] = -1;
  36. for (int i = 0; i < n; i++)
  37. {
  38. for (int j = 0; j < n; j++)
  39. {
  40. if (M[i][j] == 1 && i != j)
  41. Union(fathers, i, j);
  42. }
  43. }
  44. return Count(fathers);
  45. }
  46. };

思路2:利用dfs深度优先搜索的方法:

  1. #include <vector>
  2. using namespace std;
  3. // dfs深度优先遍历
  4. class Solution {
  5. public:
  6. int findCircleNum(vector<vector<int>>& M) {
  7. int m = M.size();
  8. if (m == 0)
  9. return 0;
  10. vector<bool>flag(m, false);
  11. int circle = 0; // 朋友圈个数
  12. for (int i = 0; i < m; i++) // 第一次就把和这个人有关系的都遍历了,置为true
  13. {
  14. if (flag[i] == false) // 没有遍历的再去遍历;已经遍历的
  15. {
  16. mark(M, flag, i);
  17. circle++;
  18. }
  19. }
  20. return circle;
  21. }
  22. void mark(vector<vector<int>>& M, vector<bool>&flag, int k)
  23. {
  24. flag[k] = true;
  25. for (int i = 0; i < M.size(); i++)
  26. {
  27. if (flag[i] == false && M[k][i] == 1) // 没有遍历的,并且有朋友圈关系的,再去遍历
  28. mark(M, flag, i);
  29. }
  30. }
  31. };
  32. int main()
  33. {
  34. Solution s;
  35. vector<vector<int>> v{
  36. { 1, 0, 1, 0, 1},
  37. { 0, 1, 0, 0, 0},
  38. { 1, 0, 1, 0, 0},
  39. { 0, 0, 0, 1, 0},
  40. { 1, 0, 0, 0, 1} };
  41. s.findCircleNum(v);
  42. }

发表评论

表情:
评论列表 (有 0 条评论,318人围观)

还没有评论,来说两句吧...

相关阅读

    相关 leetcode547. 朋友

    班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈

    相关 并查集应用-leetcode547朋友

    班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈