题目
思路一 BFS
把边界中的陆地点放入队列中,再逐渐出队,把出队元素的四个方向的陆地点添加进队列,并把这个网格置0(防止该元素重复入队)。
代码一
class Solution {
public:
int numEnclaves(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
queue<int> q;
for(int i = 0; i < m; i++){
if(grid[i][0] == 1){
q.push(i * n);
grid[i][0] = 0;
}
if(grid[i][n-1] == 1){
q.push(i * n + n - 1);
grid[i][n-1] = 0;
}
}
for(int j = 0; j < n; j++){
if(grid[0][j] == 1){
q.push(j);
grid[0][j] = 0;
}
if(grid[m-1][j] == 1){
q.push((m - 1)*n + j);
grid[m-1][j] = 0;
}
}
int dirs[5] = {-1,0,1,0,-1};
while(!q.empty()){
int x = q.front()/n, y = q.front()%n;
q.pop();
for(int i = 0; i < 4; i++){
int nx = x + dirs[i], ny = y + dirs[i+1];
if(nx < 0 || nx >= m || ny < 0 || ny >=n || grid[nx][ny] == 0) continue;
//在这里标记grid[nx][ny]=0,防止被后面出队的元素重复放入,不加会超时
grid[nx][ny] = 0;
q.push(nx*n+ny);
}
}
int ans = 0;
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
if(grid[i][j] == 1)
ans++;
return ans;
}
};
思路二 并查集+DFS
定义一个超级源点,使得所有边界上的陆地网格都与超级源点连接。深度优先搜索边界上的陆地网格,使得与其相连的陆地网格也与超级源点相连。最后统计陆地网格中不与超级源点相连的点的个数。
代码二
class Solution {
public:
vector<vector<int>> g;
vector<int> p;
int m, n;
int find(int x){
int a = x;
while(x != p[x])
x = find(p[x]);
//路径压缩
// while(a != p[a]){
// int z = a;
// a = p[a];
// p[z] = x;
// }
return x;
}
bool query(int a, int b){
return find(a) == find(b);
}
void uni(int a, int b){
p[find(a)] = find(b);
}
int numEnclaves(vector<vector<int>>& grid) {
g = grid;
m = grid.size();
n = grid[0].size();
p = vector<int>(m*n+1);
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
p[i * n + j + 1] = i * n + j + 1;
}
}
for(int i = 0; i < m; i++){
if(grid[i][0] == 1 && !query(i * n + 1, 0))
dfs(i, 0);
if(grid[i][n - 1] == 1 && !query(i * n + n - 1 + 1, 0))
dfs(i, n - 1);
}
for(int j = 0; j < n; j++){
if(grid[0][j] == 1 && !query(j + 1, 0))
dfs(0, j);
if(grid[m - 1][j] == 1 && !query((m - 1) * n + j + 1, 0))
dfs(m - 1, j);
}
int ans = 0;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(grid[i][j] == 1 && !query(i * n + j + 1, 0))
ans++;
}
}
return ans;
}
int dirs[5] = {-1, 0, 1, 0, -1};
void dfs(int x, int y){
uni(x * n + y + 1, 0);
for(int i = 0; i < 4; i++){
int nx = x + dirs[i], ny = y + dirs[i + 1];
if(nx < 0 || nx >= m || ny < 0 || ny >= n) continue;
if(g[nx][ny] == 0 || query(nx * n + ny + 1,0)) continue;
dfs(nx, ny);
}
}
};