又是我们熟悉的岛屿问题,依照该题题意,我们知道,如果grid2的岛屿不是grid1的子岛屿的话,肯定grid2中出现的1在grid1的相同位置上不是1,根据这一点,我们可以这样: 我们遍历grid2,如果遇到1就搜索这个岛屿,在搜索的过程中同时比对相同位置grid1和grid2的情况,如果出现不一样的情况,我们就做个“记号”,记得我们搜索过的地方要“改变”或者用一个数组记录下,搜索完毕后,我们就根据这个记号判断该岛屿是不是子岛屿并且计数
1.DFS
class Solution {
public:
int n, m, tx, ty, sign = 1, ans = 0, nextt[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
void dfs(vector<vector<int>>& grid1, vector<vector<int>>& grid2, int x, int y)
{
if (grid2[x][y])
{
if (grid1[x][y] != grid2[x][y])//判断相同位置的情况
{
sign = 1;
}
grid2[x][y]=0;
for (int i = 0; i < 4; i++)
{
tx = x + nextt[i][0];
ty = y + nextt[i][1];
if (tx < 0 || ty < 0 || tx >= n || ty >= m || grid2[tx][ty] == 0 )
{
continue;
}
dfs(grid1, grid2, tx, ty);
}
}
}
int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
n = grid2.size();
m = grid2[0].size();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
sign = 0;//重新初始化“记号”
if (grid2[i][j] == 1)
{
dfs(grid1, grid2, i, j);
if (!sign)//判断记号情况
{
ans++;
}
}
}
}
return ans;
}
};
2.BFS(思路与上述一致)
class Solution {
public:
int n, m, tx, ty, sign = 0, ans = 0, nextt[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
int book[500][500]={0};
void bfs(vector<vector<int>>& grid1, vector<vector<int>>& grid2, int x, int y)
{
queue<pair<int,int>>q;
q.push({x,y});
pair<int,int> now;
while(!q.empty())
{
now=q.front();
int x=now.first;
int y=now.second;
q.pop();
if(grid1[x][y]!=grid2[x][y])
{
sign=1;
}
book[x][y]=1;
for(int i=0;i<4;i++)
{
tx=x+nextt[i][0];
ty=y+nextt[i][1];
if(tx<0||ty<0||tx>=n||ty>=m||grid2[tx][ty]==0||book[tx][ty])
{
continue;
}
q.push({tx,ty});
book[tx][ty]=1;
}
}
}
int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
n = grid2.size();
m = grid2[0].size();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
sign = 0;
if (grid2[i][j] == 1&&!book[i][j])
{
bfs(grid1, grid2, i, j);
if (!sign)
{
ans++;
}
}
}
}
return ans;
}
};
3.并查集
该思路稍微与上面有所不同,我们先遍历数组,如果找到一个点(在grid1中是0而在grid2中是1的),那么这个点代表的岛屿肯定不是子岛屿,我们就搜索这个岛屿,并且把它们都变成0,
那么剩下的岛屿就肯定都是子岛屿啦,我们就遍历数组,遇到1,就直接把它和它相邻的1并起来,
最后数一数有多少个“根”就行了
class Solution {
public:
vector<int> fa;
int row, col, tx, ty, nextt[4] [2] = { {0,1},{1,0},{0,-1},{-1,0} };
void init(int n)//初始化
{
fa.resize(n);
for (int i = 0; i < n; ++i)
{
fa[i] = i;
}
}
vector<pair<int, int>> directions = { {1,0},{-1,0},{0,1},{0,-1} };
int find(int x)//找 根
{
if (fa[x] == x)
{
return x;
}
else
return find(fa[x]);
}
void merge(int i, int j)//并
{
int x = find(i), y = find(j);
if (x == y)
{
return;
}
fa[x] = y;
}
void dfs(vector<vector<int>>& grid1, vector<vector<int>>& grid2, int i, int j)
{
for (const auto& dir : directions)
{
int newi = i + dir.first, newj = j + dir.second;
if (newi >= 0 && newi < row && newj >= 0 && newj < col && grid2[newi][newj] == 1)
{
grid2[newi][newj] = 0;
dfs(grid1, grid2, newi, newj);
}
}
}
int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2)
{
row = grid1.size(), col = grid1[0].size();
init(row * col+10);
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
if (grid1[i][j] == 0 && grid2[i][j] == 1)
{
grid2[i][j] = 0;
dfs(grid1, grid2, i, j);
}
}
}
//合并
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < col; ++j)
{
if (grid2[i][j] == 1)
{
for (int z = 0; z < 4; z++)
{
tx = i + nextt[z][0];
ty = j + nextt[z][1];
if (tx < 0 || ty < 0 || tx >= row || ty >= col || grid2[tx][ty] == 0)
{
continue;
}
merge(tx * col + ty,i * col + j);
}
}
else
{
merge(i * col + j, row*col);//注意这里要把那些0都并到另一个地方去
}
}
}
int ans = 0;//grid2 中 子岛屿 的 数目
for (int i = 0; i < row * col; ++i)
{
if ( i == fa[i])
++ans;
}
return ans;
}
};