并查集定义就不说了,我对并查集的理解就是将一个数组或者集合中存在关联的元素,通过findFather和merge函数联合起来。
做题时需要找到元素之间是否存在联系,然后将相关的几个元素合并,可以解出有多少组元素,哪些元素无关之类的问题
关键函数
int findFather(int x) {
//判断x是否为自己的根节点,如果是则返回x,如果不是则递归查找x的根节点
if (x == father[x]) {
return x;
}
else {
return findFather(father[x]);
}
}
void merge(int x, int y) {
//查找x和y的根节点,若根节点不同,将y的根节点faY加入到faX中
int faX = findFather(x);
int faY = findFather(y);
if (faX != faY) {
father[faY] = faX;
//这里根据题目不同可以补充
}
}
例题1:leetcode200 岛屿数量
https://leetcode-cn.com/problems/number-of-islands/
class Solution {
public:vector<int> father;
int res = 0;int find(int x) {
if (x == father[x]) {
return x;
}
else {
return find(father[x]);
}
}void merge(int x, int y) {
int faX = find(x);
int faY = find(y);
if (faX != faY) {
father[faY] = faX;
res--;
}
}int numIslands(vector<vector<char>>& grid) {
int m = grid.size();
if (m == 0) {
return 0;
}
int n = grid[0].size();
//初始化根节点数组
father.resize(m*n);
for (int i = 0; i < m*n; i++) {
father[i] = i;
}
//找到所有陆地,此时默认为独立节点
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
res++;
}
}
}
//如果节点的上节点和左节点为陆地,则合并,每次合并之后独立的陆地数减一
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
//除了第一排是否有上节点为1
if (i > 0 && grid[i][j] == '1'&&grid[i - 1][j] == '1') {
merge((i - 1)*n + j, i*n + j);
}
//除了第一列是否有左节点为1
if (j > 0 && grid[i][j] == '1'&&grid[i][j - 1] == '1') {
merge(i*n + j - 1, i*n + j);
}
}
}
return res;
}
};
例题2、leetcode684冗余连接
https://leetcode-cn.com/problems/redundant-connection/
class Solution {
public:vector<int> father, res;
int find(int x) {
if (x == father[x]) {
return x;
}
else {
return find(father[x]);
}
}void merge(int x, int y) {
int faX = find(x);
int faY = find(y);
//如果是说明已经连接上了,这组连接多余,如果不是则将y的根节点加入faX
if (faX != faY) {
father[faY] = faX;
}
else if (faX == faY) {
res.clear();
res.push_back(x);
res.push_back(y);
}
}vector<int> findRedundantConnection(vector<vector<int>>& edges) {
res.resize(2, 0);
int m = edges.size();
//初始化根节点数组
father.resize(2 * m, 0);
for (int i = 0; i < 2 * m; i++) {
father[i] = i;
}
//依次判断每组连接的两个节点是否有同一个根节点
for (int i = 0; i < m; i++) {
int a = edges[i][0];
int b = edges[i][1];
merge(a, b);
}
return res;
}
};