由于不能走回头路,因此如果用DFS判断环,要记录前一步所走的路径,不能回去,比较满分,最直接的方法是用并查集的方式直接判断环。
一般并查集在实现的时候只需要路径压缩,不需要按秩合并。
代码如下:
class UnionFind {
public:
vector<int> parent;
public:
UnionFind(int n): parent(n) {
iota(parent.begin(), parent.end(), 0);
}
int findset(int x) {
return parent[x] == x ? x : parent[x] = findset(parent[x]);
}
void unite(int x, int y) {
parent[findset(x)] = findset(y);
}
bool isUnite(int x, int y) {
return findset(x) == findset(y);
}
};
class Solution {
public:
bool containsCycle(vector<vector<char>>& grid) {
int m = grid.size(), n = grid[0].size();
UnionFind uf(n * m);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i > 0 && grid[i][j] == grid[i - 1][j]) {
if (uf.isUnite(i * n + j, (i - 1) * n + j)) {
return true;
} else {
uf.unite(i * n + j, (i - 1) * n + j);
}
}
if (j > 0 && grid[i][j] == grid[i][j -1]) {
if (uf.isUnite(i * n + j, i * n + j - 1)) {
return true;
} else {
uf.unite(i * n + j, i * n + j - 1);
}
}
}
}
return false;
}
};