问题描述:
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.
思路分析:
题目让我们求解朋友圈的数量,如果A和B是朋友,B和C是朋友,则A和C也是间接的朋友,于是A、B和C组成一个朋友圈。这属于简单典型的搜索例题,直接的解法就是DFS算法,从某个同学开始,遍历搜索其朋友,再遍历搜索其朋友的朋友,以此类推,就能找到这个同学的所有直接和间接朋友,组成一个朋友圈(注意标记已经遍历过的同学),然后再去遍历没有标记过的同学的朋友圈,由此求出朋友圈的总数量;当然也可以选择BFS算法,增加一个队列q存放当前的某个同学所有的直接朋友,思路与DFS很相似。
代码实现:
- DFS(深度优先搜索)
class Solution {
public:
int findCircleNum(vector<vector<int>>& M) {
if (M.empty())
return 0;
//朋友圈的数量
int circles = 0;
//学生的数量
int number = M.size();
std::vector<bool> visited(number, false);
for (int i = 0; i < number; i++) {
//已经访问过的同学
if (visited[i])
continue;
//找到与该同学相关系的所有同学
else {
find(M, visited, i);
circles++;
}
}
return circles;
}
void find(vector<vector<int>>& M, vector<bool>& visited, int i) {
visited[i] = true;
for (int j = 0; j < M.size(); j++) {
if (visited[j] || !M[i][j]) continue;
find(M, visited, j);
}
}
};
- BFS(广度优先搜索)
class Solution {
public:
int findCircleNum(vector<vector<int>>& M) {
if (M.empty())
return 0;
//朋友圈的数量
int circles = 0;
//学生的数量
int number = M.size();
std::vector<bool> visited(number, false);
queue<int> q;
for (int i = 0; i < number; i++) {
if (visited[i])
continue;
else {
q.push(i);
while (!q.empty()) {
int j = q.front();
q.pop();
//标记为搜索过的同学
visited[j] = true;
for (int k = 0; k < number; ++k)
{
if (visited[k] || !M[j][k])
continue;
else {
q.push(k);
}
}
}
}
circles++;
}
return circles;
}
};