给定一个非空 01 二维数组表示的网格,一个岛屿由四连通(上、下、左、右四个方向)的 1 组成,你可以认为网格的四周被海水包围。
请你计算这个网格中共有多少个形状不同的岛屿。两个岛屿被认为是相同的,当且仅当一个岛屿可以通过平移变换(不可以旋转、翻转)和另一个岛屿重合。
示例 :
11011
10000
00001
11011
给定上图,返回结果 3 。
注意:
11
1
和
1
11
是不同的岛屿,因为我们不考虑旋转、翻转操作。
1.DFS搜索到所有岛屿,并且存储其profile,然后sort排序unique去重,即为不同岛屿数量
class Solution {
public:
int m,n;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int numDistinctIslands(vector<vector<int>>& grid) {
m=grid.size();
n=grid[0].size();
vector<vector<pair<int,int>>> profiles;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==1){
vector<pair<int,int>> profile;
dfs(grid,i,j,i,j,profile);
profiles.push_back(profile);
}
}
}
sort(profiles.begin(),profiles.end());
return unique(profiles.begin(),profiles.end())-profiles.begin();
}
void dfs(vector<vector<int>>& grid,int x,int y,int i,int j,vector<pair<int,int>>& profile){
if(i<0||i>=m||j<0||j>=n||grid[i][j]==0) return;
grid[i][j]=0;
profile.push_back({i-x,j-y});
for(int k=0;k<4;k++){
int nx=i+dx[k];
int ny=j+dy[k];
dfs(grid,x,y,nx,ny,profile);
}
}
};
2.set
class Solution {
public:
int m,n;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int numDistinctIslands(vector<vector<int>>& grid) {
m=grid.size();
n=grid[0].size();
set<vector<pair<int,int>>> profiles;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]==1){
vector<pair<int,int>> profile;
dfs(grid,i,j,i,j,profile);
profiles.insert(profile);
}
}
}
//sort(profiles.begin(),profiles.end());
return profiles.size();
}
void dfs(vector<vector<int>>& grid,int x,int y,int i,int j,vector<pair<int,int>>& profile){
if(i<0||i>=m||j<0||j>=n||grid[i][j]==0) return;
grid[i][j]=0;
profile.push_back({i-x,j-y});
for(int k=0;k<4;k++){
int nx=i+dx[k];
int ny=j+dy[k];
dfs(grid,x,y,nx,ny,profile);
}
}
};