zoukankan      html  css  js  c++  java
  • leetcode 547. 朋友圈

    题目描述:

    班上有 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个学生自己在一个朋友圈。所以返回2。

    示例 2:

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

    注意:

    1. N 在[1,200]的范围内。
    2. 对于所有学生,有M[i][i] = 1。
    3. 如果有M[i][j] = 1,则有M[j][i] = 1。

    思路分析:

    思路1: 一开始以为只需要求图的连通分量个数就好了,就仿照之前岛屿的数量那道题做,利用dfs完成。结果出现了样例错误才知道这道题的真正题意。将原来的代码进行修改,这里的visited数组只需要是一维,对应每个人是否被访问过。对于每一个未被访问的人,进行dfs。dfs函数中,首先标记当前人被访问,接下来遍历他的朋友,若未被访问,则逐层深度访问其朋友。

    思路2: 利用并查集实现。首先有n个对应其朋友圈编号为其本身,此时总的朋友圈数为人的总数。接下来遍历每个关系对,若i和j是朋友,分别获取i和j的朋友圈编号,若不一致,将i的朋友圈编号改为j,即合并两个人的朋友圈,朋友圈总数减1。遍历完成后,所得的朋友圈数即为总数。

    代码:

     1 class Solution {
     2 public:
     3     void dfs(vector<vector<int>>& M, vector<int>& visited, int idx)
     4     {
     5         visited[idx] = 1;
     6         for(int j=0; j<M.size(); j++)
     7         {
     8             if(idx == j)
     9                 continue;
    10             if(visited[j] == 0 && M[idx][j])
    11             {
    12                 dfs(M, visited, j);
    13             }
    14         }
    15     }
    16     int findCircleNum(vector<vector<int>>& M) {
    17         if(M.size() == 0)
    18             return 0;
    19         vector<int> visited(M.size(), 0);
    20         int cnt = 0;
    21         for(int i=0; i<M.size(); i++)
    22         {
    23             if(visited[i] == 0 )
    24             {
    25                 cnt++;
    26                 dfs(M, visited, i);
    27             }
    28         }
    29         return cnt;
    30     }
    31 };

    思路2:

     1 class Solution {
     2 public:
     3     int find(vector<int>& pre, int x)
     4     {
     5         return pre[x] == x ? x:find(pre, pre[x]);
     6     }
     7     int findCircleNum(vector<vector<int>>& M) {
     8         if(M.size() == 0)
     9             return 0;
    10         vector<int> pre(M.size(), 0);
    11         for(int i=0; i<M.size(); i++)
    12             pre[i] = i;
    13         int group = M.size();
    14         for(int i=0; i<M.size(); i++)
    15         {
    16             for(int j=0; j<M[i].size(); j++)
    17             {
    18                 if(i!=j && M[i][j])
    19                 {
    20                     int x1 = find(pre, i);
    21                     int x2 = find(pre, j);
    22                     if(x1 != x2)
    23                     {
    24                         pre[x1] = x2;
    25                         group--;
    26                     }
    27                 }
    28             }
    29         }
    30         return group;
    31     }
    32 };
  • 相关阅读:
    Jmeter 使用技巧 (如何在linux下运行jmeter视窗界面呢)-jmeter如何模拟http发送gzip数据
    1.Jmeter 快速入门教程(一)
    4.jmeter在线并发的怎样设置
    3.jmeter jsr232 脚本获取当前测试的正在活动的线程数
    2.Jmeter 如何在jsr223 脚本中停止测试任务
    1.如何在JMeter中使用JUnit
    app电量测试
    梯度下降法实现对数几率回归
    基于C/S模式的简易聊天室
    大数据使用及现状调研报告
  • 原文地址:https://www.cnblogs.com/LJ-LJ/p/11222885.html
Copyright © 2011-2022 走看看