haopeng

有个班级,里面有N个学生,他们之中有些是朋友有些不是,比如如果A是B的朋友,B是C的朋友,那么A就是C的间接朋友,我们定义所谓的朋友圈就是由直系和间接朋友所组成的群体。

给定一个N*N的矩阵M,代表这个班级里所有学生的朋友关系,如果M[i][j] = 1,那么第i个和第j个学生就是互为直系朋友,不为1的话就不是朋友。而你的任务就是输出整个班级里总的朋友圈数量。

英语原文:

 

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

例子 1:

输入: 
[[1,1,0],
 [1,1,0],
 [0,0,1]]
输出: 2
解释:第0个和第1个学生是直系朋友,所以记为1个朋友圈。第2个学生他没什么朋友也要算一个朋友圈,所以结果为2.
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. 
The 2nd student himself is in a friend circle. So return 2.

 

 

例子 2:

输入: 
[[1,1,0],
 [1,1,1],
 [0,1,1]]
输出: 1
解释:第0个和第1个学生是直系朋友,第1和第2个也是,所以第0和第2个学生是间接朋友,三个学生都在同个朋友圈里,返回1.
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, 
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

 

注:

  1. N的范围为 [1,200].
  2. 所有学生自己对自己都是1,即M[i][i] = 1.
  3. 如果 M[i][j] = 1, 那么 M[j][i] = 1.
 
解答:
关键词是并查集,不知道的可以百度下。思路见代码注释:
 1 class Solution {
 2 public:
 3     int findCircleNum(vector<vector<int>>& M) {
 4         if (M.empty())
 5             return 0;
 6         vector<int> pre(M.size());
 7         for(int i=0; i<M.size(); i++)
 8             pre[i] = i;//先各自为组,组名也为自己的序号
 9         int group = M.size();//一开始有多少人就有多少个朋友圈,当每出现一对朋友时就减1,最后就是总的朋友圈数量了。
10         for(int i=0; i<M.size(); i++)
11         {
12             for(int j=0; j<M.size(); j++)
13             {
14                 if (i != j && M[i][j] == 1)
15                 {
16                     int x1 = find(i, pre);//x1为i所属的组
17                     int x2 = find(j, pre);//x2为j所属的组
18                     if (x1 != x2)
19                     {
20                         //如果不属于同个朋友圈的话就把i归为j的组
21                         pre[x1] = x2;
22                         group--;
23                     }
24                 }
25             }
26         }
27         return group;
28     }
29     
30 private:
31     int find(int x, vector<int>& pre)
32     {
33         return pre[x]==x ? x : pre[x] = find(pre[x], pre);//“pre[x] = ”这句为路径压缩,直接指向组的根节点,下次查询时就快很多了。
34     }
35 };

 

相关文章: