地址:https://leetcode-cn.com/problems/friend-circles/
方法一:并查集
Java 代码:
public class Solution {
private class UnionFind {
private int[] parent;
private int count;
public UnionFind(int n) {
count = n;
parent = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
}
}
public int find(int x) {
while (x != parent[x]) {
parent[x] = parent[parent[x]];
x = parent[x];
}
return x;
}
public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY) {
return;
}
count--;
parent[rootX] = rootY;
}
}
public int findCircleNum(int[][] M) {
int len = M.length;
UnionFind unionFind = new UnionFind(len);
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len; j++) {
if (M[i][j] == 1) {
unionFind.union(i, j);
}
}
}
return unionFind.count;
}
public static void main(String[] args) {
int[][] M = {{1, 1, 0},
{1, 1, 0},
{0, 0, 1}};
Solution solution = new Solution();
int res = solution.findCircleNum(M);
System.out.println(res);
}
}
方法二:深度优先遍历
C++ 代码:
#include <iostream>
#include <vector>
using namespace std;
class Solution {
private:
/**
* 记录是否被访问过
*/
vector<int> visited;
/**
* 一共 N 名学生
*/
int N;
void dfs(int u, vector<vector<int>> &M) {
if (visited[u]) {
return;
}
visited[u] = 1;
for (int i = 0; i < N; ++i) {
// 如果是朋友关系,就继续遍历下去,这是深度优先遍历
if (M[u][i]) {
dfs(i, M);
}
}
}
public:
int findCircleNum(vector<vector<int>> &M) {
N = M.size();
if (N == 0) {
return 0;
}
// 连通分量
int res = 0;
visited.assign(N, 0);
for (int i = 0; i < N; ++i) {
if (visited[i]) {
continue;
}
dfs(i, M);
res++;
}
return res;
}
};